角度“地图”运算符无法触发我的订阅

时间:2020-07-25 15:46:23

标签: angular rxjs

我使用一个HTTP拦截器来解决一些常见的响应。 当响应返回{success:true,data:'xxx'}时,我只想将'data'字段传递给订阅'xxx'。 当我使用“点击”运算符时,可以触发我的订阅。但是获得的数据订阅是“ {成功:正确,数据:'xxx'}”。 因此,我决定使用“地图”运算符,但无法触发订阅。 我的angular版本是10.0.4,rxjs版本是6.5.5。 代码如下,这是我的http拦截器:

import { Code } from '../../../code.enum.js';
import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpResponse,
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap, filter, map } from 'rxjs/operators';
import { Router } from '@angular/router';

@Injectable()
export class AppInterceptor implements HttpInterceptor {
  constructor(private router: Router) {}

  intercept(
    request: HttpRequest<unknown>,
    next: HttpHandler
  ): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      filter((res) => {
        return res.type !== 0;
      }),
      map((res: HttpResponse<{ msg; success; data; code }>) => {
        console.log('[AppInterceptor.intercept.tap] res: %o', res);
        const { msg, success, data, code } = res.body;
        if (success) {
          console.log('[AppInterceptor.intercept.tap] data: %o', data);
          return data;
        }
        if (code === Code.needLogin) {
          this.router.navigateByUrl('/login');
        }
        console.log(msg);
        throw new Error(msg);
      })
    );
  }
}

这是我的登录组件:

import { AppService } from './../app.service';
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Validators } from '@angular/forms';
import { Router } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss'],
})
export class LoginComponent implements OnInit {
  loginForm = this.fb.group({
    username: ['', Validators.required],
    password: ['', Validators.required],
  });

  constructor(
    private appService: AppService,
    private fb: FormBuilder,
    private router: Router
  ) {}

  ngOnInit(): void {}

  login() {
    if (this.loginForm.valid) {
      const { username, password } = this.loginForm.value;
      this.appService.login(username, password).subscribe((res) => {
        console.log('[LoginComponent.login] res: %o', res);
        this.router.navigateByUrl('/');
      });
      return;
    }
    console.log('nonononono');
  }
}

这是应用程序服务:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root',
})
export class AppService {

  constructor(private httpClient: HttpClient) {
  }

  login(username, password) {
    return this.httpClient.post('/login', {
      username,
      password,
    });
  }

}

控制台日志,如您所见,代码'console.log('[LoginComponent.login] res:%o',res)'从未运行过,登录API的响应数据为{success:true} : enter image description here

1 个答案:

答案 0 :(得分:2)

您的拦截器希望返回一个Observable ,否则将无法通过,请记住,即使被拦截,它在到达您的组件时仍应保持Http事件。

您可以执行以下操作:

    const evt = { ...res };
    evt.body = evt.body["data"];
    return evt;

返回仅包含“ data”属性的事件。