Angular HttpInterceptor 没有在嵌套的 Observable 上触发
Angular HttpInterceptor not firing on nested Observables
我有一个 HttpInterceptor 可以将我的 Bearer 令牌添加到对我的 WebApi 的所有调用中。
这个拦截器在我所有的简单服务调用上都能完美运行。
但我有一个地方需要调用 2 个方法并使用这两个结果来构建组合模型。我已经使用 MergeMap、ForkJoin 和 FlatMap 来嵌套可观察对象,但是 none 这些似乎触发了我的 HttpInterceptor...
这是拦截器
export class JwtInterceptor implements HttpInterceptor {
constructor(private userService: UserService) { }
public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
let currentUser = this.userService.getCurrentUser();
if (currentUser && currentUser.token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${currentUser.token}`
}
});
}
return next.handle(request);
}
}
服务调用
public getPriceList(): Observable<CuttingGapPartPrice[]> {
const list = sessionStorage.getItem(this.listSessionKey);
if (list) {
return of(JSON.parse(list) as CuttingGapPartPrice[]);
}
return super.getClient()
.get(`/api/cutting-gap-part-prices`, { headers: super.getHeaders() })
.pipe(map(response => {
sessionStorage.setItem(this.listSessionKey, JSON.stringify(response));
return response ? response as CuttingGapPartPrice[] : new Array<CuttingGapPartPrice>();
}));
}
public getPowerList(): Observable<MotorPower[]> {
const list = sessionStorage.getItem(this.listSessionKey);
if (list) {
return of(JSON.parse(list) as MotorPower[]);
}
return super.getClient()
.get(`/api/motor-power`, { headers: super.getHeaders() })
.pipe(map(response => {
sessionStorage.setItem(this.listSessionKey, JSON.stringify(response));
return response ? response as MotorPower[] : new Array<MotorPower>();
}));
}
他们各自工作完美。但是 combined/nested 他们没有。
使用 MergeMap 的嵌套调用
public getQuotationPrices(quotation: Quotation): Observable<QuotationPrices> {
return this.cuttingGapPartPriceService.getPriceList().pipe(mergeMap(prices => {
return this.motorPowerService.getPowerList().pipe(map(powers => {
var result = new QuotationPrices();
//Some custom logic
return result;
}));
}));
}
我知道我的问题与此 post 中描述的问题相当,但我只是不知道如何解决它。
编辑 - 使用 ForkJoin 的嵌套调用
public getQuotationPrices(quotation: Quotation): Observable<QuotationPrices> {
return forkJoin([this.cuttingGapPartPriceService.getPriceList(), this.motorPowerService.getPowerList()]).pipe(map(data => {
const prices = data[0];
const powers = data[1];
var result = new QuotationPrices();
return result;
}));
}
chrome 的网络选项卡中的结果
尝试展平嵌套的 observables。可能是您的内部 observables 没有被订阅 (Observables 不会 运行 除非它们是已订阅)。您可以检查 this stackblitz example 以查看嵌套的可观察对象如何不 运行ning 除非您订阅了 innerObservables 或将它们展平。另外,正如@JB Nizet 所建议的那样,如果您可以在 stackblitz
上创建一个回购协议,那就太好了
终于找到问题所在了。
它与可观察对象无关。
我在 AppModule 中提供了拦截器,但这些拦截器再次被我的 SharedModule 覆盖,因为我再次导入了 angular 的 HTTPClientModule。
删除重复导入后问题已解决。
我有一个 HttpInterceptor 可以将我的 Bearer 令牌添加到对我的 WebApi 的所有调用中。 这个拦截器在我所有的简单服务调用上都能完美运行。
但我有一个地方需要调用 2 个方法并使用这两个结果来构建组合模型。我已经使用 MergeMap、ForkJoin 和 FlatMap 来嵌套可观察对象,但是 none 这些似乎触发了我的 HttpInterceptor...
这是拦截器
export class JwtInterceptor implements HttpInterceptor {
constructor(private userService: UserService) { }
public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
let currentUser = this.userService.getCurrentUser();
if (currentUser && currentUser.token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${currentUser.token}`
}
});
}
return next.handle(request);
}
}
服务调用
public getPriceList(): Observable<CuttingGapPartPrice[]> {
const list = sessionStorage.getItem(this.listSessionKey);
if (list) {
return of(JSON.parse(list) as CuttingGapPartPrice[]);
}
return super.getClient()
.get(`/api/cutting-gap-part-prices`, { headers: super.getHeaders() })
.pipe(map(response => {
sessionStorage.setItem(this.listSessionKey, JSON.stringify(response));
return response ? response as CuttingGapPartPrice[] : new Array<CuttingGapPartPrice>();
}));
}
public getPowerList(): Observable<MotorPower[]> {
const list = sessionStorage.getItem(this.listSessionKey);
if (list) {
return of(JSON.parse(list) as MotorPower[]);
}
return super.getClient()
.get(`/api/motor-power`, { headers: super.getHeaders() })
.pipe(map(response => {
sessionStorage.setItem(this.listSessionKey, JSON.stringify(response));
return response ? response as MotorPower[] : new Array<MotorPower>();
}));
}
他们各自工作完美。但是 combined/nested 他们没有。
使用 MergeMap 的嵌套调用
public getQuotationPrices(quotation: Quotation): Observable<QuotationPrices> {
return this.cuttingGapPartPriceService.getPriceList().pipe(mergeMap(prices => {
return this.motorPowerService.getPowerList().pipe(map(powers => {
var result = new QuotationPrices();
//Some custom logic
return result;
}));
}));
}
我知道我的问题与此 post 中描述的问题相当,但我只是不知道如何解决它。
编辑 - 使用 ForkJoin 的嵌套调用
public getQuotationPrices(quotation: Quotation): Observable<QuotationPrices> {
return forkJoin([this.cuttingGapPartPriceService.getPriceList(), this.motorPowerService.getPowerList()]).pipe(map(data => {
const prices = data[0];
const powers = data[1];
var result = new QuotationPrices();
return result;
}));
}
chrome 的网络选项卡中的结果
尝试展平嵌套的 observables。可能是您的内部 observables 没有被订阅 (Observables 不会 运行 除非它们是已订阅)。您可以检查 this stackblitz example 以查看嵌套的可观察对象如何不 运行ning 除非您订阅了 innerObservables 或将它们展平。另外,正如@JB Nizet 所建议的那样,如果您可以在 stackblitz
上创建一个回购协议,那就太好了终于找到问题所在了。 它与可观察对象无关。 我在 AppModule 中提供了拦截器,但这些拦截器再次被我的 SharedModule 覆盖,因为我再次导入了 angular 的 HTTPClientModule。 删除重复导入后问题已解决。