I would like to set up a factory that does async work to return a service, and then provide that factory to a factory provider to provide that service to a component when it loads.
However, when the provider injects the TestService
into the TestComponent
, the type at runtime is ZoneAwarePromise
. I need a way to have the provider automatically "await" the promise before it injects the service into the component.
Service
export class TestService {
public test() {
return 123;
}
}
Provider and Factory
export function testFactory(auth: any, temp: any) {
return new Promise((res, rej) => {
res(new TestService());
});
}
export let testProvider =
{
provide: TestService,
useFactory: testFactory,
deps: []
};
App Module
providers: [
testProvider
]
TestComponent
import { Component, OnInit } from '@angular/core';
import { TestService } from './Test';
@Component({
selector: 'app-test'
})
export class TestComponent implements OnInit {
constructor(private testService: TestService) { }
async ngOnInit() {
console.log(this.testService.test()); // fails because the type of this.testService at runtime is "ZoneAwarePromise" instead of "TestService"
}
}
A provider is basically an object that tells Angular injector how to obtain or create a dependency. When Angular creates a new instance of a component class, it determines which services or other dependencies that component needs by looking at the constructor parameter types.
useClass - this option tells Angular DI to instantiate a provided class when a dependency is injected. useExisting - allows you to alias a token and reference any existing one. useFactory - allows you to define a function that constructs a dependency.
The useExisting provider key lets you map one token to another. In effect, the first token is an alias for the service associated with the second token, creating two ways to access the same service object.
Using Async/Await in AngularOne of the best improvements in JavaScript is the Async/Await feature introduced in the ECMAScript 7. Basically, Async/Await works on top of Promise and allows you to write async code in a synchronous manner. It simplifies the code and makes the flow and logic more understandable.
It seems Angular cannot implement the async factory function for the provider directly.
In order to do this, we need to set up a new function and hand it over to the NgModule
to do the APP_INITIALIZER job.
import {
APP_INITIALIZER,
} from '@angular/core'
function configFactory(testService: TestService) {
// do the async tasks at here
return () => testService.init()
}
@NgModule({
providers: [
{
provide: APP_INITIALIZER,
useFactory: configFactory,
deps: [TestService],
multi: true,
},
],
})
Angular4 APP_INITIALIZER won't delay initialization
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With