Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 969
nishil bhave Avatar asked Jun 23 '26 23:06

nishil bhave


1 Answers

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);
        }));
  }
}
like image 169
sebaferreras Avatar answered Jun 25 '26 18:06

sebaferreras



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!