Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 - asynchronous dependency injection

I use Angular2 v2.2.3

I've created common module with forRoot() function, like this:

    ...
    public static forRoot(): ModuleWithProviders {
    return {
        ngModule: CommonsModule,
        providers: [
            SomeOtherDependency,
            {
                provide: ConfigService,
                useFactory: ConfigFactory,
                deps: [Http]
            }                
        ]
    };

Here is my ConfigFactory:

export function ConfigFactory(http:Http):Promise<ConfigService> {    
    return http.get('confg/config.json').map(r => {
        return new ConfigService(r);
    }).toPromise();
}

I've tried to return Promise and Observable as well.

SomeOtherDependency defined in providers requires ConfigService. The problem is that Angular does not inject value resolved by promise but promise itself.

How can I force angular to wait until promise is resolved with proper dependency and only then inject it to other dependencies?

I've tried different approaches and always injected value is promise or observable. Just like the iniector ignores what type factory returned. I need to load some json files before whole application starts

like image 355
Mariusz.v7 Avatar asked Nov 27 '16 10:11

Mariusz.v7


People also ask

What is the difference between providers and ProvidedIn in Angular while using Dependency Injection?

An Injectable configured with providedIn will be tree-shaken if it is not injected by any (eagerly or lazy loaded) class in its assigned injector scope. However, an Injectable assigned to a providers array in some module/component will never be tree-shaken, even if it is not injected anywhere.

Which components can be injected as a dependency in Angular 7?

26) Which of the following components can be injected as a dependency in AngularJS? Answer: D is the correct answer. The "Application Module" can be injected as a dependency in AngularJS.

What does @inject do in Angular?

The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency. Likewise, the @Injectable() decorator indicates that a component, class, pipe, or NgModule has a dependency on a service. The injector is the main mechanism.

How is Angular Dependency Injection implemented?

The first step is to add the @Injectable decorator to show that the class can be injected. The next step is to make it available in the DI by providing it. A dependency can be provided in multiple places: At the Component level, using the providers field of the @Component decorator.


1 Answers

I've found a problem.

I was returning a promise from my factory when I needed to return function instead. Also I missed "multi" argument from provider section. Here is updated factory which works with APP_INITIALIZER:

export function ConfigFactory(config:ConfigService, http:Http):Function {
    return () => config.load(http);
}

And in module:

providers: [
    ConfigService,
    {
        provide: APP_INITIALIZER,
        useFactory: ConfigFactory,
        deps: [ConfigService, Http],
        multi: true
    },
]
like image 55
Mariusz.v7 Avatar answered Oct 22 '22 06:10

Mariusz.v7