[英]Angular with RxJS: be sure service's constructor using http.get is finished before call method
在Angular 6中,我有一个ConfigService
,要求构造函数完成正常工作:
import { HttpClient, HttpHeaders, HttpErrorResponse } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable, Subscribable, Subscription } from "rxjs";
@Injectable()
export class ConfigService {
public configKeys: any;
constructor(private http: HttpClient) {
this.http.get('config/config.json').subscribe(
data => {
this.configKeys = data;
},
(err: HttpErrorResponse) => {
console.log (err.message);
}
);
}
getDocBaseRoute() :string{
return this.configKeys.docBaseRoute;
}
getAuthenticationBaseRoute() : Subscription {
return this.configKeys.authenticationBaseRoute;
}
}
当我尝试调用该服务的方法时,会触发一个问题:
this.baseUrl = this.configservice.getAuthenticationBaseRoute();
实际上,此时configKeys
是未定义的,因此return this.configKeys.authenticationBaseRoute;
configKeys
引发错误。
因此,您可以帮助我知道如何确定在调用服务的方法之前构造函数已经完成吗?
您应该始终使用RxJS使其正常工作。
import { HttpClient, HttpErrorResponse } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { shareReplay, map } from 'rxjs/operators';
@Injectable()
export class ConfigService {
private configuration: Observable<any>;
constructor(private http: HttpClient) { }
getDocBaseRoute(): Observable<string> {
return this.getConfiguration().pipe(map(data => data.docBaseRoute));
}
getAuthenticationBaseRoute(): Observable<any> {
return this.getConfiguration().pipe(map(data => data.authenticationBaseRoute));
}
private getConfiguration(): Observable<any> {
if(!this.configuration) {
this.configuration = this.http.get('config/config.json').pipe(
catchError((error: HttpErrorResponse) => console.log(err.message)),
shareReplay()
);
}
return this.configuration;
}
}
请注意,我将Observable
而不是结果存储在属性中。 如果您不这样做,而是多次调用getConfiguration()
,那么由于时间安排,可能会发生多个HTTP调用。 为此,使用RxJS shareReplay
运算符也至关重要。
用法:
this.configservice.getAuthenticationBaseRoute().subscribe(baseRoute => this.baseUrl = baseRoute);
您无法做到这一点,这与RxJS的概念背道而驰。
我认为这更多是一个概念问题,您可以使用不同的解决方案来解决此问题:
定义configKeys
的默认值, configKeys
使getAuthenticationBaseRoute
永不失败。
处理getAuthenticationBaseRoute
内部configKeys
为null
并返回undefined
。 但是,您还必须在调用getAuthenticationBaseRoute
情况下处理这种情况。
确保在ConfigService
定义configKeys
之前,调用getAuthenticationBaseRoute
的组件/服务/组件无法调用它。
好的,我找到了一种方法:使用toPromise()将可观察的对象转换为一个Promise
import { HttpClient, HttpHeaders, HttpErrorResponse } from "@angular/common/http";
import { Injectable } from "@angular/core";
@Injectable()
export class ConfigService {
public configKeys: any;
constructor(private http: HttpClient) {
}
async getGestionDocumentBaseRoute(): Promise<string> {
await this.initialize();
return this.configKeys.gestionDocumentBaseRoute;
}
private async initialize(): Promise<boolean> {
if (!this.configKeys) {
await this.http.get('config/config.json').toPromise()
.then(
data => {
this.configKeys = data;
}
)
.catch(
(err: HttpErrorResponse) => {
console.log(err.message);
return false;
}
);
}
return true;
}
async getAuthenticationBaseRoute(): Promise<string> {
await this.initialize();
return this.configKeys.authenticationBaseRoute;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.