12

Here is the code snippet from angular.io:

{ provide: RUNNERS_UP,    useFactory:  runnersUpFactory(2), deps: [Hero, HeroService] }

...

export function runnersUpFactory(take: number) {
  return (winner: Hero, heroService: HeroService): string => {
    /* ... */
  };
};

My question is why deps property is used here? What are the general cases for using deps?

Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • 1
    See the manual https://angular.io/docs/ts/latest/api/core/index/FactoryProvider-interface.html , it is quite exhaustive on this. – Estus Flask Jan 24 '17 at 07:05
  • 1
    @estus, thanks, I've seen the manual. I usually ask a question to get a broader picture, while the manual just says that it's used with factory providers. But is it limited to it? Are there any other use cases? etc. These are the questions I have in my head – Max Koretskyi Jan 24 '17 at 07:23
  • Yes, it is limited to factories. The benefit of TS is that properties don't come out of nowhere, they are defined with interfaces (FactoryProvider here). – Estus Flask Jan 24 '17 at 07:54
  • @estus, got itl, thanks – Max Koretskyi Jan 24 '17 at 08:10

1 Answers1

15

This is a way to tell Angular dependency injections what dependencies it needs to inject to the factory function returned by runnersUpFactory.

For services there is the @Injectable() class to tell DI that it needs to analyze the constructor parameter of this class (same for @Component(), @Directive(), and @Pipe()), but this seems not to work for functions. Therefore they introduced the deps parameter.

DI will look up a provider using the key Hero and another one using HeroService and then will pass them as parameters to the factory function in the same order.

https://angular.io/docs/ts/latest/api/core/index/FactoryProvider-interface.html

deps : any[] A list of tokens which need to be resolved by the injector. The list of values is than used as arguments to the useFactory function.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    thanks, so it's basically only relevant when `useFactory` is used, correct? when the other providers are used, like `useClass`, `useValue` and `useExisting`, it has no purpose? – Max Koretskyi Jan 24 '17 at 07:21
  • 2
    Exactly - only for `useFactory` – Günter Zöchbauer Jan 24 '17 at 07:22
  • Great, thanks. Just a quick follow-up, is there any other provider besides the ones I mentioned in my previous comment? – Max Koretskyi Jan 24 '17 at 07:25
  • That's the kind of inconsistency I don't like on Angular 2 – Karl Jan 24 '17 at 07:27
  • https://github.com/angular/angular/blob/8578682dcfccc2ccccb68df37c3ebc738f98bf0e/modules/%40angular/compiler/src/compile_metadata.ts#L167-L175 – Günter Zöchbauer Jan 24 '17 at 07:29
  • 1
    @Karl A function cannot be annotated for DI with decorators, that's TS limitation. If you're after consistency, you can always annotate it like `factoryFn.parameters = [[new Inject(dep)]]` instead of `deps: [dep]`, that's common syntax for all DI. – Estus Flask Jan 24 '17 at 08:43
  • @Estus, Gunther! Thanks to both for very useful insights ;-) – Karl Jan 24 '17 at 09:50
  • @GünterZöchbauer [Are you sure they're only for `useFactory`](https://stackoverflow.com/a/48259998/859154) ? I've asksed it yesterday and was told - no. – Royi Namir Feb 03 '18 at 06:57
  • @RoyiNamir seems reasonable. Might be handy in rare (I guess) situations. Haven't seen it before. – Günter Zöchbauer Feb 03 '18 at 09:22
  • 2
    Its not documented well, but `deps` can be used with `useClass`: https://stackoverflow.com/questions/48594944/can-deps-be-also-used-with-useclass/48597926#48597926 – Michael Kang Feb 03 '18 at 14:14
  • @pixelbits thanks for the info. Royi linked to your answer already. It makes sense, it just didn't occur to me it could be useful, but I can imagine scenarios. – Günter Zöchbauer Feb 03 '18 at 14:17