【问题标题】:Why does interceptor not return data to subscriber?为什么拦截器不向订阅者返回数据?
【发布时间】:2019-04-13 22:33:33
【问题描述】:

我在最后一个 Angular 中使用了拦截器:

return next.handle(request).pipe(
      map((event: any) => {
        if (request.method == "GET") {
          return event;
        }

        if (request.method == "POST") {
          if (event.body) {
            return event.body["result"];
          }
        }

        return event;
      }));

所以,我检查它是否是 POST 请求,我希望从带有密钥 result 的 JSON 中获取数据。

我也尝试在 Observer 中返回数据:

if (event.body) {
   return Observable.of(event.body["result"]);
}

订阅是:

this.method.subscribe(res => {
    console.log(res);
});

看这张图:

console.log(event); // This is default event - first selected area 
console.log(eventToSend); /./ This is modified   - second  selected area

区别在于HttpResponse类型,缺少第二个修改对象eventToSend

【问题讨论】:

  • 你能在 StackBlitz 上复制这个吗?也尝试在错误和完成的情况下记录。
  • 我有完整的代码,我不知道使用是否正确,我应该返回观察者并从地图解析数据吗?
  • 一个 http 拦截器应该返回一个 Observable>。 angular.io/api/common/http/HttpInterceptor。这段代码没有多大意义。你想达到什么目的?
  • 我不这么认为。如果你这样做,那么你将不得不在其中使用switchMap 而不是map
  • 因此每个响应都有结构{"result": {}},我需要解析它并返回没有result key的数据,这是主要目的。

标签: angular angular-http-interceptors angular7


【解决方案1】:

由于您的拦截器需要返回完整的event(类型为Observable<HttpEvent<any>>)而不仅仅是响应body,但您仍希望在响应body 中只获得result,试试这个:

return next.handle(request).pipe(
  map((event: any) => {
    // Removing this as it is redundant
    /*if (request.method == "GET") {
      return event;
    }*/

    if (request.method == "POST") {
      if (event.body) {
        const eventToSend = { ...event };
        eventToSend.body = event.body["result"];
        return eventToSend;
      }
    }
    return event;
  }));

在这里,我们传播整个event 对象,然后用body['result'] 重新分配其上的body 属性

这里有一个Sample StackBlitz 供您参考。

【讨论】:

  • 是的,看起来很真实
  • 还是不行,订阅者看不到响应
  • @OPV,我已经更新了我的答案。我还为您的参考添加了一个示例 StackBlitz。您能否检查更新的答案是否适合您?
  • HttpEvents 不是 POJO。它们是特定类的实例,它们是不可变的,但具有允许创建具有不同主体的副本的 clone() 方法。 angular.io/api/common/http/HttpEventangular.io/api/common/http/HttpResponse。拦截器应该返回一个实际的 HttpEvent,而不是 POJO。
  • 问题是它需要 HttpResponse 但我尝试只返回数据
【解决方案2】:

我使用这种方法解决了这个问题:

return next.handle(request).pipe(
      map((event: any) => {
        if (request.method == "POST") {
          if (request.body["$type"] == "LoginRequest") {
            return event;
          }

          if (event.body) {
            event.body = event.body["result"];
          }
        }

        return event;
      }),

      catchError((error: HttpErrorResponse) => {
        if (error.status === 401) {
          this.route.navigate(["/login"]);
        }
        return throwError(
          "Ошибка сервера RequestInterception: " + error.message || error
        );
      })
    );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 2020-09-15
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多