Lai*_*irg 5 rxjs ionic-framework angular angular-httpclient
在我这里,UserService我有一个用户Observable对象,该对象保存已UserModel登录用户ngOnInit()的身份。为进行测试,我在登录过程中实现了该对象:
this.userService.authenticate('###', '###')
.subscribe(res => console.log('authenticated'));
Run Code Online (Sandbox Code Playgroud)
private userSource = new BehaviorSubject<UserModel>(null);
public user = this.userSource.asObservable();
Run Code Online (Sandbox Code Playgroud)
我的UserModel提供了一个称为authKey的属性,用于API身份验证。
在我ProjectService我想要做的API请求; 为此,UserModel必须存储在中的api密钥。只可能订阅用户属性,但是我读到有关避免在服务内部进行订阅的信息。
题
如何将该订阅与管道/映射连接起来?我的方法是以下代码;但这感觉像是不好的代码。
suggest(term: string): Observable<ProjectModel[]> {
return this.userSrv.user.pipe(
mergeMap((user: UserModel) => {
const options = {params: {'access-token': user.accessToken}};
return this.http.get<ProjectModel[]>(this.conf.url, options).pipe(
map(response => {
// mapping the projects ...
return projects;
})
);
})
);
}
Run Code Online (Sandbox Code Playgroud)
正如前面的答案中已经指出的,HTTP 拦截器最适合您的用例。
基本思想如下:
import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
import {mergeMap,map} from 'rxjs/operators';
import {Observable} from 'rxjs';
function isLoginRequest(req: HttpRequest<any>): boolean {
// implement
}
@Injectable()
export class AccessTokenInterceptor implements HttpInterceptor {
constructor(private readonly userService: UserService){}
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
if(isLoginRequest(req)) return next.handle(req);
return this.userService.user.pipe(
map(user => req.clone({setParams:{'access-token': user.accessToken}})),
mergeMap(req => next.handle(req))
);
}
}
Run Code Online (Sandbox Code Playgroud)
不要忘记注册此拦截器,如文档中所示。
通过使用这个,你原来的服务功能被简化为:
suggest(term: string): Observable<ProjectModel[]> {
return this.http.get<ProjectModel[]>(this.conf.url).pipe(
map(response => {
// mapping the projects ...
})
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
295 次 |
| 最近记录: |