Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Async Factory Provider

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"
    }
}
like image 621
Sharpiro Avatar asked Sep 16 '17 18:09

Sharpiro


People also ask

What is Factory provider in Angular?

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.

What is useClass useFactory in Angular?

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.

What is useExisting in Angular?

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.

Can we use async await in Angular?

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.


1 Answers

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,
    },
  ],
})

See Also

Angular4 APP_INITIALIZER won't delay initialization

like image 64
Huan Avatar answered Oct 03 '22 03:10

Huan