【发布时间】:2019-06-07 11:37:30
【问题描述】:
我有一个带有 HTTP 拦截器的 Angular 5 应用程序,它在拦截请求时调用另一个服务。
我想使用配置文件使服务可配置,因此我尝试使用在应用初始化期间异步加载配置的服务(使用 APP_INITIALIZER 挂钩)。
问题是,我要使用的服务在配置服务完成从配置文件加载配置之前被实例化。
有没有办法将服务实例化推迟到配置服务完成加载配置之后?
代码
您可以在stackblitz 中查看完整示例。
最相关的部分如下:
interceptor.service.ts
export class InterceptorService implements HttpInterceptor {
constructor(private dependency: InjectedDependencyService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// use InjectedDependencyService to do something on every intercepted request
const userId = this.dependency.getUserId();
console.log("user id:", userId);
return next.handle(request);
}
}
injected-dependency.service.ts
export class InjectedDependencyService {
userId;
constructor(private initializer: InitializerService) {
this.userId = initializer.config.id;
}
// Do something that relies on the configuration being initialized
getUserId() {
console.log("Is configuration initialized?", !!this.initializer.config.id)
return this.userId;
}
}
initializer.service.ts
@Injectable()
export class InitializerService {
config = {};
constructor(private http: HttpClient) { }
initialize() {
// TODO replace with link to a config file
const url = "https://jsonplaceholder.typicode.com/users/1";
return this.http.get(url).toPromise().then(response => {
this.config = response;
console.log("App initialized", this.config);
}, e => console.error(e));
}
}
app.module.ts
...
export function initializerServiceFactory(initializerService: InitializerService) {
return () => initializerService.initialize();
}
...
providers: [
InitializerService,
InjectedDependencyService,
{
provide: APP_INITIALIZER,
useFactory: initializerServiceFactory,
deps: [InitializerService],
multi: true
},
{
provide: HTTP_INTERCEPTORS,
useClass: InterceptorService,
multi: true
}
]
...
结果
【问题讨论】:
-
在您的拦截器中,检查您的配置是否已加载,如果没有,请将您的 api 调用添加到将等待配置加载的订阅者。
-
你必须从 initializerService.initialize() 返回有效的 Promise
-
我不确定我是否明白这一点。但我认为,如果您正在设置拦截器,则获取配置的第一个请求将在获取配置本身之前通过它
-
@Florian 正如 Doguita 所建议的那样,问题在于拦截器拦截了来自 initializerService 的调用,然后实例化了服务。请参阅已接受的答案以获取解决方案。
-
@isevcik 从
Promise.all创建的承诺有什么无效的?
标签: angular angular-httpclient-interceptors