简体   繁体   中英

Setting default requests header from ionic storage using http interceptor - Angular 5 - Ionic 3

I'm trying to set a token value in all request headers using angular 5 new HTTP client. Below is my code:

import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
import {Observable} from "rxjs/Observable";
import { Storage } from '@ionic/storage';
import {Globals} from '../globals/globals';

@Injectable()
export class Interceptor implements HttpInterceptor {
  token: string;
  constructor(private storage: Storage, private global: Globals){ 
    this.storage.get('token').then((val) => {
      this.token = val;
    });
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log(this.token) //undefined "only for first time on app start"
    req = req.clone({
      setHeaders: {
        'Token': this.token,
        'Version': this.global.version,
      }
    });
    return next.handle(req);
  }
}

While adding the token in request header works, but there is a bad exception. It doesn't work for the first time. The problem is with js async nature, req.clone gets executed before getting token from the storage. Because Ionic storage returns promise, so how to handle this situation for the first time?

You can merge both async request (getting the token and handling the request) to execute the later when the token is ready (instead of getting it in the constructor):

// -------------------------------------------------------------------------
// Please note that I'm using lettable/pipeable operators (RxJS > 5.5.x)
// https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md
// -------------------------------------------------------------------------

import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from "rxjs/Observable";
import { Storage } from '@ionic/storage';
import { Globals } from '../globals/globals';

// New imports!
import { fromPromise } from 'rxjs/observable/fromPromise';
import { mergeMap } from 'rxjs/operators/mergeMap';

@Injectable()
export class Interceptor implements HttpInterceptor {

  constructor(private storage: Storage, private global: Globals){ }

  getToken(): Promise<any> {
    return this.storage.get('token');
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return fromPromise(this.getToken()).pipe(
        mergeMap(token => {

            // Use the token in the request
            req = req.clone({
                setHeaders: {
                    'Token': token,
                    'Version': this.global.version,
                }
            });

            // Handle the request
            return next.handle(req);
        }));
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM