非同期作業を行ってサービスを返すファクトリをセットアップし、そのファクトリをファクトリプロバイダーに提供して、コンポーネントがロードされたときにそのサービスをコンポーネントに提供したいと思います。
ただし、プロバイダーがTestService
をTestComponent
に挿入する場合、実行時の型はZoneAwarePromise
です。プロバイダーがサービスをコンポーネントに注入する前に、プロバイダーがプロミスを自動的に「待機」する方法が必要です。
サービス
export class TestService {
public test() {
return 123;
}
}
プロバイダーと工場
export function testFactory(auth: any, temp: any) {
return new Promise((res, rej) => {
res(new TestService());
});
}
export let testProvider =
{
provide: TestService,
useFactory: testFactory,
deps: []
};
アプリモジュール
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"
}
}
Angularはプロバイダーの非同期ファクトリ関数を直接実装できないようです。
これを行うには、新しい関数を設定し、それをNgModule
に渡して、APP_INITIALIZERジョブを実行する必要があります。
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,
},
],
})