Search code examples
angularangular2-servicesangular-providers

Angular2 Provider that depends on other Providers


I have several modules within my Angular2 application, that provide Services and Configuration.

Now I'd like to include the @ngrx/store which collects the available reducers from my modules.


Here's the bootstrap code:

import {OpaqueToken} from 'angular2/core'
import {provideStore} from '@ngrx/store'

export const REDUCER_TOKEN = new OpaqueToken('Reducer');

bootstrap(AppComponent, [
    provide(REDUCER_TOKEN, { useClass: Module1Reducers, multi: true }),
    provide(REDUCER_TOKEN, { useClass: Module2Reducers, multi: true }),
    // old code: provideStore({module1, module2}, {module1:{}, module2:[]})
    provideStore(/* INSERT CODE HERE */)
]);

The INSERT CODE HERE comment should be replaced with something, that uses all REDUCER_TOKEN providers.

How can I achieve that?


Solution

  • I don't see a way to pass it to provideStore() directly.

    provideStore creates and returns an array of providers. My attempt is to first add the providers provideStore() creates and then in a second step override the REDUCER that depends on REDUCER_TOKEN:

    bootstrap(AppComponent, [
        provide(REDUCER_TOKEN, { useClass: Module1Reducers, multi: true }),
        provide(REDUCER_TOKEN, { useClass: Module2Reducers, multi: true }),
        // add generated providers
        provideStore(),
        // override `REDUCER` provider
        provide(REDUCER, {
          deps: [REDUCER_TOKEN],
          useFactory(reducer){
            if(typeof reducer === 'function'){
              return reducer;
            }
    
            return combineReducers({
                "foo":reducer[0].reducerFunction, 
                "bar":reducer[1].reducerFunction
            });
          }
        }),
    ]);
    

    If multiple providers are added for the same token (or type), without multi: true, then only the one added last takes effect.

    Built according to this provideStore() implementation https://github.com/ngrx/store/blob/master/src/ng2.ts#L56

    -- not tested --