拦截触发前调用通用API

问题描述 投票:0回答:1

我的拦截器代码:

    import { Injectable } from '@angular/core';
    import {
      HttpInterceptor,
      HttpRequest,
      HttpHandler,
      HttpEvent,
      HttpErrorResponse,
      HttpHeaders,
      HttpResponse
    } from '@angular/common/http';
    import { Observable, throwError } from 'rxjs';
    import { catchError, map } from 'rxjs/operators';
    import { ApiService } from 'src/app/modules/services/api.service';
    import { Router } from '@angular/router';
    
    
    @Injectable({
      providedIn: 'root'
    })
    export class HttpErrorService implements HttpInterceptor {
      constructor(
        private apiService: ApiService,
        private router: Router,
      ) { }
    
      intercept(request: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> {
    
        request = request.clone({
          headers: new HttpHeaders({
            'Content-Type':  'application/json',
            'Accept': 'application/json',
            'Access-Control-Allow-Headers': 'Content-Type',
          })
        });
        
        return this.apiService.getSession().subscribe((res:any)=>{
           if(res.data.existingSession == 'active'){
              this.router.navigate(['/login']);
           } else{
            return next.handle(request).pipe(
              map((event: HttpEvent<any>) => {
                return event;
              }),
              catchError((error: HttpErrorResponse) => {
                return throwError(() => { return 'Something bad happened; please try again later.' })
              }));
           }
        });
    
    
      }
    }

我试图在拦截器拦截每个 api 调用之前调用 api。但我无法添加有效的返回类型并收到此错误:

“订阅”类型缺少“Observable”类型中的以下属性:源、操作员、提升、订阅以及另外 3 个属性

尝试过 switchMap

import { Injectable } from '@angular/core';
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpErrorResponse,
  HttpHeaders,
  HttpResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { ApiService } from 'src/app/modules/services/api.service';
import { Router } from '@angular/router';
@Injectable({
  providedIn: 'root'
})
export class HttpErrorService implements HttpInterceptor {
  constructor(
    private apiService: ApiService,
    private router: Router,
  ) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    request = request.clone({
      headers: new HttpHeaders({
        'Content-Type':  'application/json',
        'Accept': 'application/json',
        'Access-Control-Allow-Headers': 'Content-Type',
      })
    });

    return this.apiService.getSession().pipe(
      switchMap((res: any) => {
        if(res.data.existingSession == 'active'){
          this.router.navigate(['/login']);
        } else{
          return next.handle(request).pipe(
            map((event: HttpEvent<any>) => {
              return event;
            }),
            catchError((error: HttpErrorResponse) => {
              return throwError(() => 'Something bad happened; please try again later.');
            })
          );
        })
        }
    );
  }
}

它触发拦截器n次。但 api 调用没有发生。 在拦截器拦截每个 api 调用之前,我需要调用 1 个 api。

angular interceptor angular-http-interceptors
1个回答
0
投票

您可以尝试一下

shareReplay
吗?它将重播之前的值,指定的次数,在下面的示例中重播20次!

import { Injectable } from '@angular/core';
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpErrorResponse,
  HttpHeaders,
  HttpResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map, shareReplay } from 'rxjs/operators';
import { ApiService } from 'src/app/modules/services/api.service';
import { Router } from '@angular/router';
@Injectable({
  providedIn: 'root'
})
export class HttpErrorService implements HttpInterceptor {
  constructor(
    private apiService: ApiService,
    private router: Router,
  ) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    request = request.clone({
      headers: new HttpHeaders({
        'Content-Type':  'application/json',
        'Accept': 'application/json',
        'Access-Control-Allow-Headers': 'Content-Type',
      })
    });

    return this.apiService.getSession().pipe(
      shareReplay(20), // <- reuse previous value for 20 times the http calls are made then make the api call again!
      switchMap((res: any) => {
        if(res.data.existingSession == 'active'){
          this.router.navigate(['/login']);
        } else{
          return next.handle(request).pipe(
            map((event: HttpEvent<any>) => {
              return event;
            }),
            catchError((error: HttpErrorResponse) => {
              return throwError(() => 'Something bad happened; please try again later.');
            })
          );
        })
        }
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.