Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

264
Visualizações
Angular (v5) service is getting constructed before APP_INITIALIZER promise resolves

I'm expecting Angular to wait until my loadConfig() function resolves before constructing other services, but it is not.

app.module.ts

export function initializeConfig(config: AppConfig){
    return () => config.loadConfig();
}

@NgModule({
     declarations: [...]
     providers: [
          AppConfig,
         { provide: APP_INITIALIZER, useFactory: initializeConfig, deps: [AppConfig], multi: true }
     ] })
export class AppModule {

}

app.config.ts

@Injectable()
export class AppConfig {

    config: any;

    constructor(
        private injector: Injector
    ){
    }

    public loadConfig() {
        const http = this.injector.get(HttpClient);

        return new Promise((resolve, reject) => {
            http.get('http://mycoolapp.com/env')
                .map((res) => res )
                .catch((err) => {
                    console.log("ERROR getting config data", err );
                    resolve(true);
                    return Observable.throw(err || 'Server error while getting environment');
                })
                .subscribe( (configData) => {
                    console.log("configData: ", configData);
                    this.config = configData;
                    resolve(true);
                });
        });
    }
}

some-other-service.ts

@Injectable()
export class SomeOtherService {

    constructor(
        private appConfig: AppConfig
    ) {
         console.log("This is getting called before appConfig's loadConfig method is resolved!");
    }
 }

The constructor of SomeOtherService is getting called before the data is received from the server. This is a problem because then the fields in SomeOtherService do not get set to their proper values.

How do I ensure SomeOtherService's constructor gets called only AFTER the loadConfig's request is resolved?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

I had also a simmilar issue what solved the issue for me was to use Observable methods and operators to do everything. Then in the end just use the toPromise method of the Observable to return a Promise. This is also simpler because you don't need to create a promise yourself.

The AppConfig service will then look something like that:

import { Injectable, Injector } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { tap } from 'rxjs/operators/tap';

@Injectable()
export class AppConfig {

    config: any = null;

    constructor(
        private injector: Injector
    ){
    }

    public loadConfig() {
        const http = this.injector.get(HttpClient);

        return http.get('https://jsonplaceholder.typicode.com/posts/1').pipe(
          tap((returnedConfig) => this.config = returnedConfig)
        ).toPromise();
        //return from([1]).toPromise();
    }
}

I'm using the new pipeable operators in rxjs which is recommended by Google for Angular 5. The tap operator is equivalent to the old do operator.

I have also created a working sample on stackblitz.com so you can se it working. Sample link

over 4 years ago · Santiago Trujillo Relatório

0

  async loadConfig() {
        const http = this.injector.get(HttpClient);

        const configData = await http.get('http://mycoolapp.com/env')
                    .map((res: Response) => {
                        return res.json();
                    }).catch((err: any) => {
                        return Observable.throw(err);
                    }).toPromise();
                this.config = configData;
        });
    }

The await operator is used to wait for a Promise. It can only be used inside an async function.

It is working fine.

over 4 years ago · Santiago Trujillo Relatório

0

Injector does not wait for observables or promises and there is no code that could make it happen.

You should use custom Guard or Resolver to ensure that config is loaded before initial navigation completes.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda