Angular 8 HTTP INTERCEPTOR中断订阅

时间:2019-11-25 01:51:26

标签: angular typescript rxjs

我试图建立一个Angular 8项目,该项目允许我使用HTTP INTERCEPTORS模拟api调用。基本思想是,如果我在ng服务脚本中添加--configuration = mock标志,则拦截器将注入到我的app.module中,并且我将从JSON文件而不是外部API获取数据。我或多或少地跟随着这个例子,https://stackblitz.com/edit/angular-mock-http-interceptor 由于某种原因,当我使用拦截器时,我的组件对数据服务的订阅已损坏。据我所知,我要在模拟服务上构建与实时服务相同的数组。无法弄清楚为什么会坏。这是该服务的getter和Observable:

getUsers() {
    this.http.get<any>('https://jsonplaceholder.typicode.com/users')
    .subscribe(fetchedUsers => {
      this.users = fetchedUsers;
      this.usersUpdated.next([...this.users]);
    });
  }

  getUsersUpdatedListener() {
    return this.usersUpdated.asObservable();
  }

调用服务的组件:

ngOnInit() {
    this.usersService.getUsers();
    this.usersSub = this.usersService.getUsersUpdatedListener()
    .subscribe((users: User[]) => {
      this.users = users;
    });
  }

最后是拦截器类:

import { Injectable, Injector } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import * as users from '../../assets/mockData/users.json';

const urls = [
  {
      url: 'https://jsonplaceholder.typicode.com/users',
      json: users
  }
];


@Injectable()
export class HttpMockRequestInterceptor implements HttpInterceptor {
    constructor(private injector: Injector) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        for (const element of urls) {
            if (request.url === element.url) {
                console.log('Loaded from json : ' + request.url);
                return of(new HttpResponse({ status: 200, body: ((element.json) as any).default }));
            }
        }
        console.log('Loaded from http call :' + request.url);
        return next.handle(request);
    }
}

可以在这里查看整个项目: https://github.com/reynoldsblair/learn-http

拦截器为什么破坏我的项目?

1 个答案:

答案 0 :(得分:2)

您的拦截器非常好,我只是拉了您的项目及其user-list.component.ts,这是错误的,您尝试在this.usersService.getUsersUpdatedListener()触发后订阅this.usersService.getUsers();流,这使您大开眼界有点比赛条件。在调用getUsers之前移动预订逻辑可以解决该问题,并且每次在HttpRequestInterceptorHttpMockRequestInterceptor上都有效

 ngOnInit() {
    this.usersSub = this.usersService.getUsersUpdatedListener()
      .subscribe((users: User[]) => {
        this.users = users;
      });
    this.usersService.getUsers();
  }