example - Angular 2: servicios que consumen otros servicios antes de llamar a un método
router events angular 4 (1)
Tengo este escenario.
backend.json
{
"devServer": "http://server1/''",
"proServer" : "http://server2/''",
"use" : "devServer"
}
global.service.ts
import {Injectable} from ''@angular/core'';
import {Http, HTTP_PROVIDERS, Response, RequestOptions, URLSearchParams} from ''@angular/http'';
@Injectable()
export class GlobalService {
constructor(private _http: Http){}
getBackendServer(){
return this.server = this._http.get(''./backend.json'')
.map((res:Response) => res.json())
}
}
Y tengo este otro servicio: search.service.ts
import {Injectable} from ''@angular/core'';
import {Http, HTTP_PROVIDERS, Response, RequestOptions, URLSearchParams} from ''@angular/http'';
import {GlobalService} from ''../services/global.service'';
import ''rxjs/add/operator/map'';
@Injectable()
export class SearchService {
server;
constructor( private _http: Http, private gs: GlobalService ) {
this.server = gs.getBackendServer().subscribe(
(data) => {
this.server = data[data.use];
},
(err) => {
console.log(err);
}
);
}
DoGeneralSearch(params:Search){
console.log(this.server);
let options = this.buildOptions(params);
return this._http.get(this.server + ''room/search'', options)
.map((res:Response) => res.json())
}
}
Lo que quiero hacer: Parece obvio: quiero mantener la información sobre la URL del servidor de fondo en un archivo JSON. Y el servicio global debe devolver el servidor para que pueda usarse en cualquier método del servicio de búsqueda.
El problema es: el método DoGeneralSearch () se ejecuta antes de que el servicio global sea capaz de resolver la tarea de leer el archivo JSON y devolver el resultado. Entonces, tengo un this.server = Subscriber {isUnsubscriptions: false, syncErrorValue: null, syncErrorThrown: false, syncErrorThrowable: false, isStopped: false ...} en lugar del resultado en sí.
Necesito encontrar alguna forma de evitar que el método DoGeneralSearch se ejecute justo después de resolver la variable this.server.
Alguna sugerencia ?
Creo que podrías precargar tales pistas al inicio de la aplicación.
Para esto, puede aprovechar el servicio
APP_INITIALIZER
.
La aplicación esperará a que se resuelva la promesa devuelta antes de comenzar realmente.
Aquí hay una muestra:
provide(APP_INITIALIZER, {
useFactory: (service:GlobalService) => () => service.load(),
deps:[GlobalService, HTTP_PROVIDERS], multi: true
})
El método de
load
quisiera algo así:
load():Promise<Site> {
var promise = this.http.get(''config.json'').map(res => res.json()).toPromise();
promise.then(config => this.devServer = config.devServer);
return promise;
}
Entonces puede usar directamente el
devServer
(sincrónicamente) ...
Vea este problema en github para más detalles: