ngxtension/ngxtension-platform

why extraProviders doesn't accept service(provider)?

jon9090 opened this issue · 1 comments

I want to pass a lazy component to the foo service as an option without making a direct call. I aim to achieve this using an injection token. Additionally, I want to ensure that the scope of foo is limited to the component instance. This way, I can pass both the injection token and foo to the component providers in the usual manner.

Since I'm using ngxtension, is it possible to provide both the injection token and the foo class in a single provide function?

the problem is in extraProviders:

const [injectFoo, provideFoo] = createNoopInjectionToken<{
  dialogComponent: () => Promise<Type<FooComponent>>;
}>('foo options', { extraProviders: [Foo] }); // <----

argument of type '{ extraProviders: (typeof Foo)[]; }' is not assignable to parameter of type 'Pick<CreateInjectionTokenOptions<() > => void, []>, "extraProviders"> & Record<string, never>'.
Type '{ extraProviders: (typeof Foo)[]; }' is not assignable to type 'Record<string, never>'.
Property 'extraProviders' is incompatible with index signature.
Type '(typeof Foo)[]' is not assignable to type 'never

stackblitz demo

Here is the code:

import { Component, Injectable, Type } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { createNoopInjectionToken } from 'ngxtension/create-injection-token';

@Component({
  standalone: true,
  template: 'I am foo',
})
export class FooComponent {}

const [injectFoo, provideFoo] = createNoopInjectionToken<{
  dialogComponent: () => Promise<Type<FooComponent>>;
}>('foo options', { extraProviders: [Foo] });

@Injectable({ providedIn: 'root' })
export class Foo {
  foo = injectFoo();

  async work() {
    const dialogComponent = await this.foo.dialogComponent();
    console.log({ dialogComponent });
  }
}

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <h1>Hello from {{ name }}!</h1>
    <a target="_blank" href="https://angular.dev/overview">
      Learn more about Angular
    </a>
  `,
  providers: [
    provideFoo({
      dialogComponent: () => import('./main').then((m) => m.FooComponent),
    }),
  ],
})
export class App {
  name = 'Angular';
}

bootstrapApplication(App);

@eneajaho @nartc Is this something I'm unable to accomplish with the extension?