0

I have the following HTTP provider which is called using the subscribe method like on the example below. Problem is that during the GET request I need to get token value saved in the local storage which is happening using another provider in function getToken in HTTP provider. I am not able to get token value in HTTP call. I would like to ask, how to do it in the right way, please?

Thanks for any advice.

this.httpProvider.doGetRequest(Constants.API_SERVER_URL+Constants.API_ENDPOINT_THREADS)
      .subscribe(res => {
        console.log(res);
        this.loading.dismiss();
      }, (error) => {
        console.log(error);
        this.err = error;
        this.loading.dismiss();
        this.presentToast();
      });

HTTP provider class :

@Injectable()
export class HttpProvider {

  constructor(public http: HttpClient,
              public dataProvider: DataProvider,
              public locStor: LocalStorageProvider) {
    console.log('Hello HttpProvider Provider');
  }

  public doGetRequest(url: string) {
    return this.http.get(url, this.getHeaders());
  }

  public doPostRequest(url: string, params: any) {
    return this.http.post(url, params);
  }

  public getHeaders() {
    return {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Authorization': 'Bearer test',
        'token': this.getToken()
      },
      params: new HttpParams()
    };
  }

  private getToken() {

    this.locStor.getValue(Constants.LS_KEY_USER_TOKEN).then((val) => {
      return val;
    });
    //return this.locStor.getValue(Constants.LS_KEY_USER_TOKEN);
    //return '222';
    //return this.dataProvider.getUser().token;
  }

}

Updated version

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import {HttpHeaders} from "@angular/common/http";
import {LocalStorageProvider} from "../local-storage/local-storage";
import {Constants} from "../../app/constants";
import {Headers} from "@angular/http";
import {HttpParams} from "@angular/common/http";
import {DataProvider} from "../data/data";
import 'rxjs/add/observable/fromPromise';
import { Observable } from 'rxjs/Observable';
import {FromObservable} from "rxjs-compat/observable/FromObservable";
import {PromiseObservable} from "rxjs-compat/observable/PromiseObservable";


/*
  Generated class for the HttpProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class HttpProvider {

  constructor(public http: HttpClient,
              public dataProvider: DataProvider,
              public locStor: LocalStorageProvider) {
    console.log('Hello HttpProvider Provider');
  }

  public doGetRequest(url: string) {
    //return this.http.get(url);

    return Observable.fromPromise((this.getHeaders()).flatMap((headers) => {
      this.http.get(url, headers);
    }));

  }

  public doPostRequest(url: string, params: any) {
    return this.http.post(url, params);
  }

  public getHeaders() {
    /*
    return {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Authorization': 'Bearer test',
        'token': this.getToken
      },
      params: new HttpParams()
    };
    */

    return this.locStor.getValue(Constants.LS_KEY_USER_TOKEN).then((val) => {
      return {
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'Authorization': 'Bearer test',
          'token': val
        },
        params: new HttpParams()
      };
    });

  }

  private getToken() {
    this.locStor.getValue(Constants.LS_KEY_USER_TOKEN);
    /*
    this.locStor.getValue(Constants.LS_KEY_USER_TOKEN).then((val) => {
      return val;
    });
    */
    //return this.locStor.getValue(Constants.LS_KEY_USER_TOKEN);
    return '222';
    //return this.dataProvider.getUser().token;
  }

}
redrom
  • 11,502
  • 31
  • 157
  • 264

1 Answers1

0

I would do something like this:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromPromise';
import 'rxjs/add/operator/mergeMap'; 

@Injectable()
export class HttpProvider {

  constructor(public http: HttpClient,
              public dataProvider: DataProvider,
              public locStor: LocalStorageProvider) {
    console.log('Hello HttpProvider Provider');
  }

  public doGetRequest(url: string) {
    return Observable.fromPromise(this.getHeaders()).flatMap((headers) => {
      this.http.get(url, headers);
    });
  }

  public doPostRequest(url: string, params: any) {
    return this.http.post(url, params);
  }

  public getHeaders() {
    return getToken()
      .then((token) => ({
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'Authorization': 'Bearer test',
          'token': token,
        },
        params: new HttpParams()
      });
  }

  private getToken() {
    this.locStor.getValue(Constants.LS_KEY_USER_TOKEN)
  }

}
Leo
  • 741
  • 6
  • 14
  • from returns "is not function" exception. Is possible that namespace of the imported class has been renamed? I'm using Angular with Ionic 3. from(this.getHeaders()).flatMap((headers) => { – redrom Jan 21 '19 at 20:32
  • Oh, then can you try importing `import { Observable } from 'rxjs/Observable';` and replace `return from` by `return Observable.fromPromise` ? – Leo Jan 22 '19 at 08:11
  • After change I getting : ERROR TypeError: __WEBPACK_IMPORTED_MODULE_5_rxjs_Observable__.Observable.fromPromise is not a function Is possible to do it without rxjs or provide link to some tutorial please? I found migration Guide to ver. 6, but there is a lot of replacement of from: see https://github.com/reactivex/rxjs/blob/HEAD/docs_app/content/guide/v6/migration.md – redrom Jan 22 '19 at 08:21
  • Could you try adding `import 'rxjs/add/observable/fromPromise';` this line above `Observable` import ? Seems pretty similar to https://github.com/zyra/ionic-image-loader/issues/166 – Leo Jan 22 '19 at 08:41
  • Now it returns core.js:1449 ERROR TypeError: this.getHeaders(...).flatMap is not a function I added the second version of class into question. – redrom Jan 22 '19 at 11:21
  • My bad, with angular 6 you need to import operators separately, you need to add `import 'rxjs/add/operator/mergeMap';` as well. See https://stackoverflow.com/questions/39441629/flatmap-missing-after-upgrading-to-rc-6-and-rxjs-beta-11 – Leo Jan 22 '19 at 13:00