angular - 在角度 7 中使用装饰器时 rxjs 流中断
问题描述
错误:e1:You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
代码:
// interceptor
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor(private auth: AuthService) { }
@delayForToken()
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
//code to augment token to request
return next.handle(req);
}
}
//..
// decorator
export function delayForToken(observableName: string) {
let auth: AuthService;
return (target, key, descriptor) => {
if (descriptor === undefined) {
descriptor = Object.getOwnPropertyDescriptor(target, key);
}
const om = descriptor.value;
descriptor.value = function (...args) {
auth = (!auth) ? injector.get(AuthService) : auth;
const ags = args;
const ths = this;
return auth.onToken().pipe(take(1)).subscribe(() => {
return om.apply(ths, ags);
});
};
return descriptor;
};
}
//..
//following is slightly irrelevant, adding them for completeness
//AuthService
private tokenSub = new ReplaySubject<string>(1);
constructor(private afAuth: AngularFireAuth){
this.afAuth.idToken.subscribe((tok: string) => {
this.tokenSub.next(tok);
}
}
public onToken(): Observable<string> {
return this.tokenSub.asObservable();
}
//..
//app.module
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true }]
//..
//component
this.rest.hitserver('param1').subscribe((response: RspType[]) => {
this.rsps = response;
}, (error) => { console.log('e1:' + error); }, () => { });
//..
//app.module
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true }]
意图:我正在尝试延迟 http 请求,直到我获得 idToken 设置,以便我可以将它增加到请求中。
更新:最终只在组件中使用注释,在拦截器中重复了逻辑switchMap
(感谢Fan Cheung):
// @delayForToken() - Removed this annotation
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.auth.tok) {
return next.handle(this.addTokenToReq(req, this.auth.tok));
}
return this.auth.onToken().pipe(take(1), switchMap((token: string) => {
return next.handle(this.addTokenToReq(req, this.auth.tok));
}));
}
}
如果有办法让这个问题与装饰器一起工作,那么这个问题就会有答案。
解决方案
推荐阅读
- javascript - VueJS DOM 未在组件中更新
- python - Windows:获取 python 项目使用的所有模块/包
- vb.net - 得到错误“表达式不产生值”
- graphql - GraphQL 条件必填字段指令
- bash - 使用 sed 计算跳过标题和尾记录的行数的 shell 脚本(文件的 n-2 行)
- ruby-on-rails-5 - Rails 5 - fields_for 和更新操作 - 无法理解如何更新/保存
- java - Maven 存储库有一个无效的 java.lang.IllegalStateException
- excel - Microsoft 图形 API - 更新单元格上的错误 307
- rabbitmq - 用于消息队列 / RabbitMQ 的 Vapor Swift 客户端
- reactjs - 在 React 中更改字段名称