Can factory provider have optional dependencies?









up vote
3
down vote

favorite












For example:



@NgModule (
providers: [
provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [SOME_DEP]

)
class MyModule


Can useFactory have optional dependencies?










share|improve this question

























    up vote
    3
    down vote

    favorite












    For example:



    @NgModule (
    providers: [
    provide: MyService,
    useFactory: (optionalDep) => new MyService(optionalDep)
    deps: [SOME_DEP]

    )
    class MyModule


    Can useFactory have optional dependencies?










    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      For example:



      @NgModule (
      providers: [
      provide: MyService,
      useFactory: (optionalDep) => new MyService(optionalDep)
      deps: [SOME_DEP]

      )
      class MyModule


      Can useFactory have optional dependencies?










      share|improve this question













      For example:



      @NgModule (
      providers: [
      provide: MyService,
      useFactory: (optionalDep) => new MyService(optionalDep)
      deps: [SOME_DEP]

      )
      class MyModule


      Can useFactory have optional dependencies?







      angular typescript dependency-injection






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Sep 1 '16 at 18:54









      Krzysztof Bogdan

      456213




      456213






















          5 Answers
          5






          active

          oldest

          votes

















          up vote
          7
          down vote













          According to official doc, you can do the following:



          const Location = new InjectionToken('location');
          const Hash = new InjectionToken('hash');

          const injector = Injector.create([
          provide: Hash,
          useFactory: (location: string) => `Hash for: $location`,
          // use a nested array to define metadata for dependencies.
          deps: [[new Optional(), Location]]
          ]);

          expect(injector.get(Hash)).toEqual('Hash for: null');


          See https://angular.io/api/core/FactoryProvider#example for more






          share|improve this answer



























            up vote
            4
            down vote













            I have found such a workaround:



            class OptionalDepHolder 
            constructor(@Optional() @Inject(SOME_DEP) public optionalDep)


            @NgModule (
            providers: [
            provide: MyService,
            useFactory: (holder) => new MyService(holder.optionalDep)
            deps: [OptionalDepHolder]

            )
            class MyModule





            share|improve this answer



























              up vote
              0
              down vote













              Factory accepts a function.



              Decorators in typescript can apply on: class declaration, method, accessor, property, or parameter.



              In other words, currently you can only decorate a class and class members.




              parameter refers to the parameter of a method, not a function.




              So, since you can't decorate function and more so parameters in a function you can't set the @Optional tag.



              This a language/spec limitation that might change in the future.



              Another thing to note is that the metadata feature supported by typescript and consumed by angular using reflect-metadata is designed to work on classes. This is of course nonsense, classes are functions... but this is the general mental model.



              According to the documentation, the deps array accepts provider tokens which means you can't hint about a dependency being optional.



              It is a good idea to have support for optional dependencies in factories. You should open a GH issue with a feature request!






              share|improve this answer



























                up vote
                0
                down vote













                It is indeed possible to declare an optional dependency for a factory provider.



                export const MY_OPTIONAL_SERVICE_PARAMETER = new OpaqueToken('my_optional_service_parameter');
                export const myOptionalServiceParameterDefault = 42;


                Then, in your providers list, provide the default using a value provider



                @NgModule(
                providers: [

                provide: MY_OPTIONAL_SERVICE_PARAMETER,
                useValue: myOptionalServiceParameterDefault
                ,

                provide: MyService,
                useFactory: (optionalParam) => new MyService(optionalParam)
                deps: [MY_OPTIONAL_SERVICE_PARAMETER]

                )
                export class Module


                The service will use the provided default value of the parameter (which could be undefined), unless the consumer overrides the value later in the list of providers.



                The HttpModule from @angular/http uses this pattern to provide the optional dependency RequestOptions to its services.






                share|improve this answer





























                  up vote
                  0
                  down vote













                  so I've been trying to solve it. Check this:



                  @NgModule (
                  providers: [
                  provide: MyService,
                  useFactory: (optionalDep) => new MyService(optionalDep)
                  deps: [[new Optional(), new Inject(SOME_DEP)]]

                  )
                  class MyModule





                  share|improve this answer




















                    Your Answer






                    StackExchange.ifUsing("editor", function ()
                    StackExchange.using("externalEditor", function ()
                    StackExchange.using("snippets", function ()
                    StackExchange.snippets.init();
                    );
                    );
                    , "code-snippets");

                    StackExchange.ready(function()
                    var channelOptions =
                    tags: "".split(" "),
                    id: "1"
                    ;
                    initTagRenderer("".split(" "), "".split(" "), channelOptions);

                    StackExchange.using("externalEditor", function()
                    // Have to fire editor after snippets, if snippets enabled
                    if (StackExchange.settings.snippets.snippetsEnabled)
                    StackExchange.using("snippets", function()
                    createEditor();
                    );

                    else
                    createEditor();

                    );

                    function createEditor()
                    StackExchange.prepareEditor(
                    heartbeatType: 'answer',
                    convertImagesToLinks: true,
                    noModals: true,
                    showLowRepImageUploadWarning: true,
                    reputationToPostImages: 10,
                    bindNavPrevention: true,
                    postfix: "",
                    imageUploader:
                    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                    allowUrls: true
                    ,
                    onDemand: true,
                    discardSelector: ".discard-answer"
                    ,immediatelyShowMarkdownHelp:true
                    );



                    );













                    draft saved

                    draft discarded


















                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f39278930%2fcan-factory-provider-have-optional-dependencies%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown

























                    5 Answers
                    5






                    active

                    oldest

                    votes








                    5 Answers
                    5






                    active

                    oldest

                    votes









                    active

                    oldest

                    votes






                    active

                    oldest

                    votes








                    up vote
                    7
                    down vote













                    According to official doc, you can do the following:



                    const Location = new InjectionToken('location');
                    const Hash = new InjectionToken('hash');

                    const injector = Injector.create([
                    provide: Hash,
                    useFactory: (location: string) => `Hash for: $location`,
                    // use a nested array to define metadata for dependencies.
                    deps: [[new Optional(), Location]]
                    ]);

                    expect(injector.get(Hash)).toEqual('Hash for: null');


                    See https://angular.io/api/core/FactoryProvider#example for more






                    share|improve this answer
























                      up vote
                      7
                      down vote













                      According to official doc, you can do the following:



                      const Location = new InjectionToken('location');
                      const Hash = new InjectionToken('hash');

                      const injector = Injector.create([
                      provide: Hash,
                      useFactory: (location: string) => `Hash for: $location`,
                      // use a nested array to define metadata for dependencies.
                      deps: [[new Optional(), Location]]
                      ]);

                      expect(injector.get(Hash)).toEqual('Hash for: null');


                      See https://angular.io/api/core/FactoryProvider#example for more






                      share|improve this answer






















                        up vote
                        7
                        down vote










                        up vote
                        7
                        down vote









                        According to official doc, you can do the following:



                        const Location = new InjectionToken('location');
                        const Hash = new InjectionToken('hash');

                        const injector = Injector.create([
                        provide: Hash,
                        useFactory: (location: string) => `Hash for: $location`,
                        // use a nested array to define metadata for dependencies.
                        deps: [[new Optional(), Location]]
                        ]);

                        expect(injector.get(Hash)).toEqual('Hash for: null');


                        See https://angular.io/api/core/FactoryProvider#example for more






                        share|improve this answer












                        According to official doc, you can do the following:



                        const Location = new InjectionToken('location');
                        const Hash = new InjectionToken('hash');

                        const injector = Injector.create([
                        provide: Hash,
                        useFactory: (location: string) => `Hash for: $location`,
                        // use a nested array to define metadata for dependencies.
                        deps: [[new Optional(), Location]]
                        ]);

                        expect(injector.get(Hash)).toEqual('Hash for: null');


                        See https://angular.io/api/core/FactoryProvider#example for more







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Feb 1 at 16:38









                        maxime1992

                        10.4k43371




                        10.4k43371






















                            up vote
                            4
                            down vote













                            I have found such a workaround:



                            class OptionalDepHolder 
                            constructor(@Optional() @Inject(SOME_DEP) public optionalDep)


                            @NgModule (
                            providers: [
                            provide: MyService,
                            useFactory: (holder) => new MyService(holder.optionalDep)
                            deps: [OptionalDepHolder]

                            )
                            class MyModule





                            share|improve this answer
























                              up vote
                              4
                              down vote













                              I have found such a workaround:



                              class OptionalDepHolder 
                              constructor(@Optional() @Inject(SOME_DEP) public optionalDep)


                              @NgModule (
                              providers: [
                              provide: MyService,
                              useFactory: (holder) => new MyService(holder.optionalDep)
                              deps: [OptionalDepHolder]

                              )
                              class MyModule





                              share|improve this answer






















                                up vote
                                4
                                down vote










                                up vote
                                4
                                down vote









                                I have found such a workaround:



                                class OptionalDepHolder 
                                constructor(@Optional() @Inject(SOME_DEP) public optionalDep)


                                @NgModule (
                                providers: [
                                provide: MyService,
                                useFactory: (holder) => new MyService(holder.optionalDep)
                                deps: [OptionalDepHolder]

                                )
                                class MyModule





                                share|improve this answer












                                I have found such a workaround:



                                class OptionalDepHolder 
                                constructor(@Optional() @Inject(SOME_DEP) public optionalDep)


                                @NgModule (
                                providers: [
                                provide: MyService,
                                useFactory: (holder) => new MyService(holder.optionalDep)
                                deps: [OptionalDepHolder]

                                )
                                class MyModule






                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Sep 1 '16 at 21:41









                                Krzysztof Bogdan

                                456213




                                456213




















                                    up vote
                                    0
                                    down vote













                                    Factory accepts a function.



                                    Decorators in typescript can apply on: class declaration, method, accessor, property, or parameter.



                                    In other words, currently you can only decorate a class and class members.




                                    parameter refers to the parameter of a method, not a function.




                                    So, since you can't decorate function and more so parameters in a function you can't set the @Optional tag.



                                    This a language/spec limitation that might change in the future.



                                    Another thing to note is that the metadata feature supported by typescript and consumed by angular using reflect-metadata is designed to work on classes. This is of course nonsense, classes are functions... but this is the general mental model.



                                    According to the documentation, the deps array accepts provider tokens which means you can't hint about a dependency being optional.



                                    It is a good idea to have support for optional dependencies in factories. You should open a GH issue with a feature request!






                                    share|improve this answer
























                                      up vote
                                      0
                                      down vote













                                      Factory accepts a function.



                                      Decorators in typescript can apply on: class declaration, method, accessor, property, or parameter.



                                      In other words, currently you can only decorate a class and class members.




                                      parameter refers to the parameter of a method, not a function.




                                      So, since you can't decorate function and more so parameters in a function you can't set the @Optional tag.



                                      This a language/spec limitation that might change in the future.



                                      Another thing to note is that the metadata feature supported by typescript and consumed by angular using reflect-metadata is designed to work on classes. This is of course nonsense, classes are functions... but this is the general mental model.



                                      According to the documentation, the deps array accepts provider tokens which means you can't hint about a dependency being optional.



                                      It is a good idea to have support for optional dependencies in factories. You should open a GH issue with a feature request!






                                      share|improve this answer






















                                        up vote
                                        0
                                        down vote










                                        up vote
                                        0
                                        down vote









                                        Factory accepts a function.



                                        Decorators in typescript can apply on: class declaration, method, accessor, property, or parameter.



                                        In other words, currently you can only decorate a class and class members.




                                        parameter refers to the parameter of a method, not a function.




                                        So, since you can't decorate function and more so parameters in a function you can't set the @Optional tag.



                                        This a language/spec limitation that might change in the future.



                                        Another thing to note is that the metadata feature supported by typescript and consumed by angular using reflect-metadata is designed to work on classes. This is of course nonsense, classes are functions... but this is the general mental model.



                                        According to the documentation, the deps array accepts provider tokens which means you can't hint about a dependency being optional.



                                        It is a good idea to have support for optional dependencies in factories. You should open a GH issue with a feature request!






                                        share|improve this answer












                                        Factory accepts a function.



                                        Decorators in typescript can apply on: class declaration, method, accessor, property, or parameter.



                                        In other words, currently you can only decorate a class and class members.




                                        parameter refers to the parameter of a method, not a function.




                                        So, since you can't decorate function and more so parameters in a function you can't set the @Optional tag.



                                        This a language/spec limitation that might change in the future.



                                        Another thing to note is that the metadata feature supported by typescript and consumed by angular using reflect-metadata is designed to work on classes. This is of course nonsense, classes are functions... but this is the general mental model.



                                        According to the documentation, the deps array accepts provider tokens which means you can't hint about a dependency being optional.



                                        It is a good idea to have support for optional dependencies in factories. You should open a GH issue with a feature request!







                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Sep 1 '16 at 20:59









                                        Shlomi Assaf

                                        1,252813




                                        1,252813




















                                            up vote
                                            0
                                            down vote













                                            It is indeed possible to declare an optional dependency for a factory provider.



                                            export const MY_OPTIONAL_SERVICE_PARAMETER = new OpaqueToken('my_optional_service_parameter');
                                            export const myOptionalServiceParameterDefault = 42;


                                            Then, in your providers list, provide the default using a value provider



                                            @NgModule(
                                            providers: [

                                            provide: MY_OPTIONAL_SERVICE_PARAMETER,
                                            useValue: myOptionalServiceParameterDefault
                                            ,

                                            provide: MyService,
                                            useFactory: (optionalParam) => new MyService(optionalParam)
                                            deps: [MY_OPTIONAL_SERVICE_PARAMETER]

                                            )
                                            export class Module


                                            The service will use the provided default value of the parameter (which could be undefined), unless the consumer overrides the value later in the list of providers.



                                            The HttpModule from @angular/http uses this pattern to provide the optional dependency RequestOptions to its services.






                                            share|improve this answer


























                                              up vote
                                              0
                                              down vote













                                              It is indeed possible to declare an optional dependency for a factory provider.



                                              export const MY_OPTIONAL_SERVICE_PARAMETER = new OpaqueToken('my_optional_service_parameter');
                                              export const myOptionalServiceParameterDefault = 42;


                                              Then, in your providers list, provide the default using a value provider



                                              @NgModule(
                                              providers: [

                                              provide: MY_OPTIONAL_SERVICE_PARAMETER,
                                              useValue: myOptionalServiceParameterDefault
                                              ,

                                              provide: MyService,
                                              useFactory: (optionalParam) => new MyService(optionalParam)
                                              deps: [MY_OPTIONAL_SERVICE_PARAMETER]

                                              )
                                              export class Module


                                              The service will use the provided default value of the parameter (which could be undefined), unless the consumer overrides the value later in the list of providers.



                                              The HttpModule from @angular/http uses this pattern to provide the optional dependency RequestOptions to its services.






                                              share|improve this answer
























                                                up vote
                                                0
                                                down vote










                                                up vote
                                                0
                                                down vote









                                                It is indeed possible to declare an optional dependency for a factory provider.



                                                export const MY_OPTIONAL_SERVICE_PARAMETER = new OpaqueToken('my_optional_service_parameter');
                                                export const myOptionalServiceParameterDefault = 42;


                                                Then, in your providers list, provide the default using a value provider



                                                @NgModule(
                                                providers: [

                                                provide: MY_OPTIONAL_SERVICE_PARAMETER,
                                                useValue: myOptionalServiceParameterDefault
                                                ,

                                                provide: MyService,
                                                useFactory: (optionalParam) => new MyService(optionalParam)
                                                deps: [MY_OPTIONAL_SERVICE_PARAMETER]

                                                )
                                                export class Module


                                                The service will use the provided default value of the parameter (which could be undefined), unless the consumer overrides the value later in the list of providers.



                                                The HttpModule from @angular/http uses this pattern to provide the optional dependency RequestOptions to its services.






                                                share|improve this answer














                                                It is indeed possible to declare an optional dependency for a factory provider.



                                                export const MY_OPTIONAL_SERVICE_PARAMETER = new OpaqueToken('my_optional_service_parameter');
                                                export const myOptionalServiceParameterDefault = 42;


                                                Then, in your providers list, provide the default using a value provider



                                                @NgModule(
                                                providers: [

                                                provide: MY_OPTIONAL_SERVICE_PARAMETER,
                                                useValue: myOptionalServiceParameterDefault
                                                ,

                                                provide: MyService,
                                                useFactory: (optionalParam) => new MyService(optionalParam)
                                                deps: [MY_OPTIONAL_SERVICE_PARAMETER]

                                                )
                                                export class Module


                                                The service will use the provided default value of the parameter (which could be undefined), unless the consumer overrides the value later in the list of providers.



                                                The HttpModule from @angular/http uses this pattern to provide the optional dependency RequestOptions to its services.







                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Nov 18 '16 at 12:07

























                                                answered Nov 17 '16 at 23:55









                                                ovangle

                                                5591620




                                                5591620




















                                                    up vote
                                                    0
                                                    down vote













                                                    so I've been trying to solve it. Check this:



                                                    @NgModule (
                                                    providers: [
                                                    provide: MyService,
                                                    useFactory: (optionalDep) => new MyService(optionalDep)
                                                    deps: [[new Optional(), new Inject(SOME_DEP)]]

                                                    )
                                                    class MyModule





                                                    share|improve this answer
























                                                      up vote
                                                      0
                                                      down vote













                                                      so I've been trying to solve it. Check this:



                                                      @NgModule (
                                                      providers: [
                                                      provide: MyService,
                                                      useFactory: (optionalDep) => new MyService(optionalDep)
                                                      deps: [[new Optional(), new Inject(SOME_DEP)]]

                                                      )
                                                      class MyModule





                                                      share|improve this answer






















                                                        up vote
                                                        0
                                                        down vote










                                                        up vote
                                                        0
                                                        down vote









                                                        so I've been trying to solve it. Check this:



                                                        @NgModule (
                                                        providers: [
                                                        provide: MyService,
                                                        useFactory: (optionalDep) => new MyService(optionalDep)
                                                        deps: [[new Optional(), new Inject(SOME_DEP)]]

                                                        )
                                                        class MyModule





                                                        share|improve this answer












                                                        so I've been trying to solve it. Check this:



                                                        @NgModule (
                                                        providers: [
                                                        provide: MyService,
                                                        useFactory: (optionalDep) => new MyService(optionalDep)
                                                        deps: [[new Optional(), new Inject(SOME_DEP)]]

                                                        )
                                                        class MyModule






                                                        share|improve this answer












                                                        share|improve this answer



                                                        share|improve this answer










                                                        answered Nov 11 at 17:25









                                                        Jan Kremeň

                                                        1




                                                        1



























                                                            draft saved

                                                            draft discarded
















































                                                            Thanks for contributing an answer to Stack Overflow!


                                                            • Please be sure to answer the question. Provide details and share your research!

                                                            But avoid


                                                            • Asking for help, clarification, or responding to other answers.

                                                            • Making statements based on opinion; back them up with references or personal experience.

                                                            To learn more, see our tips on writing great answers.





                                                            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                                            Please pay close attention to the following guidance:


                                                            • Please be sure to answer the question. Provide details and share your research!

                                                            But avoid


                                                            • Asking for help, clarification, or responding to other answers.

                                                            • Making statements based on opinion; back them up with references or personal experience.

                                                            To learn more, see our tips on writing great answers.




                                                            draft saved


                                                            draft discarded














                                                            StackExchange.ready(
                                                            function ()
                                                            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f39278930%2fcan-factory-provider-have-optional-dependencies%23new-answer', 'question_page');

                                                            );

                                                            Post as a guest















                                                            Required, but never shown





















































                                                            Required, but never shown














                                                            Required, but never shown












                                                            Required, but never shown







                                                            Required, but never shown

































                                                            Required, but never shown














                                                            Required, but never shown












                                                            Required, but never shown







                                                            Required, but never shown







                                                            Popular posts from this blog

                                                            Top Tejano songwriter Luis Silva dead of heart attack at 64

                                                            ReactJS Fetched API data displays live - need Data displayed static

                                                            政党