首页 文章

在Angular HttpClient拦截器中使用promise

提问于
浏览
10

我可以在 HttpInterceptor 内使用诺言吗?例如:

export class AuthInterceptor implements HttpInterceptor{
this.someService.someFunction()
    .then((data)=>{
       //do something with data and then
       return next.handle(req);
    });
}

为什么我需要这个?因为我需要在向服务器发出请求之前获取一个令牌以添加到请求标头 .

我的拦截器:

@Injectable()
export class AuthInterceptor implements HttpInterceptor{

    constructor(private authService: AuthService){}

    intercept(req: HttpRequest<any>, next: HttpHandler) : Observable<HttpEvent<any>>{
        console.log('Intercepted!');
        // return next.handle(req);
        this.authService.getToken()
            .then((token)=>{
                console.log(token);
                const reqClone = req.clone({
                    headers: req.headers
                            .set('Authorization', 'Bearer ' + token)
                            .append('Content-Type', application/json')
                });
                console.log(reqClone);
                return next.handle(reqClone);
            })
            .catch((err)=>{
                console.log('error in interceptor' + err);
                return null;
            });
    }
}

请求:

this.http.post(this.baseURL + 'hero', data)
                    .subscribe(
                            (res: any) => {
                                console.log('Saved Successfully.');
                                console.log(res);
                            },
                            (err: any) => {
                                console.log('Save Error.' + err);
                            }
                        );

我面临的问题:

  • 我在承诺解决之前得到了这个错误 .

You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

承诺resloves我得到我的令牌但错误后 .

3 回答

  • 6

    UPDATE: using rxjs@6.x

    import { from, Observable } from 'rxjs';
    import { switchMap } from 'rxjs/operators';
    
    @Injectable()
    export class AuthInterceptor implements HttpInterceptor {
    
        constructor(private authService: AuthService){}
    
        intercept(request: HttpRequest<any>, next: HttpHandler) : Observable<HttpEvent<any>>{
            return from(this.authService.getToken())
                  .pipe(
                    switchMap(token => {
                       const headers = request.headers
                                .set('Authorization', 'Bearer ' + token)
                                .append('Content-Type', application/json');
                       const requestClone = request.clone({
                         headers 
                        });
                      return next.handle(requestClone);
                    })
                   );
        }
    }
    

    ORIGINAL ANSWER

    是的,您可以将所需的服务注入到拦截器的构造函数方法中,并在 intercept 的实现中检索该值,创建一个新的更新的http请求并处理它 .

    我对承诺不满意,所以你可以尝试以下方法:

    import { fromPromise } from 'rxjs/observable/fromPromise';
    
    @Injectable()
    export class AuthInterceptor implements HttpInterceptor{
    
        constructor(private authService: AuthService){}
    
        intercept(req: HttpRequest<any>, next: HttpHandler) : Observable<HttpEvent<any>>{
            return fromPromise(this.authService.getToken())
                  .switchMap(token => {
                       const headers = req.headers
                                .set('Authorization', 'Bearer ' + token)
                                .append('Content-Type', application/json');
                       const reqClone = req.clone({
                         headers 
                        });
                      return next.handle(reqClone);
                 });
        }
    }
    
  • 20

    对于RxJS 6我已经更新了Jota.Toledo的答案:

    import { fromPromise } from 'rxjs/observable/fromPromise';
    
    @Injectable()
    export class AuthInterceptor implements HttpInterceptor{
    constructor(private authService: AuthService){}
    intercept(req: HttpRequest<any>, next: HttpHandler) : Observable<HttpEvent<any>>{
        return fromPromise(this.authService.getToken())
              .pipe(switchMap(token => {
                   const headers = req.headers
                            .set('Authorization', 'Bearer ' + token)
                            .append('Content-Type', application/json');
                   const reqClone = req.clone({
                     headers 
                    });
                  return next.handle(reqClone);
             }));
     }  
    }
    
  • 1

    轮到我了(感谢Jota.Toledo和Capripio):

    1)切换"fromPromise"至"from" - > fromPromise does not exist on type Observable

    2)修复'application / json'报价

    import { Observable, from } from 'rxjs';
    import { switchMap } from 'rxjs/operators';
    
    @Injectable()
    export class AuthInterceptor implements HttpInterceptor {
    
      constructor(private authService: AuthService){}
    
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
          return from(this.authService.getToken()).pipe(
            switchMap(token => {
                const headers = req.headers
                    .set('Authorization', 'Bearer ' + token)
                    .append('Content-Type', 'application/json');
                const reqClone = req.clone({
                    headers
                });
                return next.handle(reqClone);
            }));
       }
    }
    

    我的RxJ版本:“6.2.2”希望有所帮助!

相关问题