Set default header from ionic storage [reward:)]

Greetings.

i’m pretty much stuck with setting a default JWT authorization header.
The problem is that ionic storage returns a promise and i can’t fin out the right way to use it.

import {Injectable} from "@angular/core";
import {BaseRequestOptions, RequestOptions, RequestOptionsArgs} from "@angular/http";
import { Storage } from '@ionic/storage';


@Injectable()
export class MyRequestOptions extends BaseRequestOptions {
  constructor(private storage: Storage) {
    super();
    this.headers.set('Content-Type', 'application/json');
  }
  merge(options?: RequestOptionsArgs): RequestOptions {
    const newOptions = super.merge(options);

    console.log("setting auth header");

    function setAuthHeader(storage) {
      return storage.get('jwt_token').then(value => {
        newOptions.headers.set('Authorization',`Bearer ${value}`);
        return newOptions;
      });
    }

    return setAuthHeader(this.storage).then(()=>{
      return newOptions;
    })
  }
}

In this case i receive Cannot read property 'merge' of undefined error.

I follow the example : https://blog.alex-miller.co/angular/2017/05/13/default-headers-in-angular.html

So, not really getting how cat i use a value from storage.

Thank you.

I’m surprised that even compiled, because merge() isn’t returning what it says it is supposed to. You have two options: either retrieve the token earlier (such as at constructor time) and somehow refrain from ever calling merge() before that is done (which is tricky), or change merge() to return a Promise<RequestOptions>. To avoid execution context problems, never type the word ‘function’ inside of one: always use arrow functions or lambdas.

1 Like

yep it didn’t compiled. i just show what i’ve tried to do.

yes, and that more of the question - how i do that?

last option i’ve tried:

@Injectable()
export class MyRequestOptions extends BaseRequestOptions {
  constructor(private storage: Storage) {
    super();
    this.headers.set('Content-Type', 'application/json');
  }
  merge(options?: RequestOptionsArgs): RequestOptions {
    const newOptions = super.merge(options);

    console.log("setting auth header");
    return this.getApiToken().flatMap( data => {
      newOptions.headers.set('Authorization',`Bearer ${data}`);
      return newOptions;
    });
  }

  getApiToken(): Observable<RequestOptions> {
    return Observable.fromPromise(this.storage.get('jwt_token'));
  }

-> .flatMap() don’t work in this case

Also tried let api_token = await this.storage.get('jwt_token'); -> await doesn`t work here for some reason.

" or change merge() to return a Promise<RequestOptions>" - tried, thats not possible =>
Class 'MyRequestOptions' incorrectly extends base class 'BaseRequestOptions'. Types of property 'merge' are incompatible. Type '(options?: RequestOptionsArgs) => Promise<RequestOptions>' is not assignable to type '(options?: RequestOptionsArgs) => RequestOptions'. Type 'Promise<RequestOptions>' is not assignable to type 'RequestOptions'. Property 'method' is missing in type 'Promise<RequestOptions>'.

Spent 3 hours trying.
20$ in bitcoins for solution.

still not solved…

I have the same issue, was it solved?