Search code examples
angularpostgettoken

How could I send the token returned from a post request in a get request in Angular


I need to send a token that I receive in a post request. I have to send the token in a get request, what I am doing is to save the token returned by the post request in one, notice that in GetToken I send it to show by console and if it is shown, that is, the assignment if it is doing, but when I try to print it from ObternerInmueble() it prints empty, I do not know why?

Here is my code:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders} from '@angular/common/http';
import { Inmueble } from '../modelos/inmueble';

@Injectable({
  providedIn: 'root'
})
export class HostlistService {
  cabecera = {
    'Accept': 'application/json',
    'Authorization': ""
  }

  parametros = {
    'grant_type':'client_credentials',
    'client_id': 1,
    'client_secret': 'clientSecret'
  }

  constructor(public http: HttpClient) {
  }

  obtenerToken(){
    return this.http.post<any>('URL',this.parametros).subscribe(
      result => {
        this.cabecera.Authorization=result.token_type+" "+result.access_token;
        console.log(this.cabecera.Authorization);  //here I can see that the value is being allocated
        this.obtenerInmuebles().subscribe();

      },error =>{
        console.log(error);
      }
    );
  }

  obtenerInmuebles() {
    console.log("Authorization-----------_>"+this.cabecera.Authorization);
    return this.http.get<any>('URL',{ headers: new HttpHeaders(this.cabecera) 
    });
  }

  mostrarCabecera(){
    console.log("CABECERA::::::::"+this.cabecera.Authorization);
  }
}

This is where he called the methods:

import { Component, OnInit } from '@angular/core';
import { HostlistService } from '../servicios/hostlist.service';
import {$,jQuery} from 'jquery';
import { Inmueble } from '../modelos/inmueble';

@Component({
  selector: 'app-slider',
  templateUrl: './slider.component.html',
  styleUrls: ['./slider.component.css']
})

export class SliderComponent implements OnInit {
  inmuebles: Inmueble[] = [];
  i: number=0;

  url: string = "http://crm.seaconfiable.com/upload/";

  constructor(private hostlistService: HostlistService) { }
  ngOnInit() {
    this.hostlistService.obtenerToken();
    this.hostlistService.obtenerInmuebles().subscribe(
      result => {
        console.log("INMUEBLES",result.data);
      },error =>{
        console.log(error);
      }
    );
  }
}

Here is the image of the browser console where you can see that the Authorization header is being sent empty (blank):

consola del navegador


Solution

  • The problem is in the following lines -

    this.hostlistService.obtenerToken();
    this.hostlistService.obtenerInmuebles().subscribe
    

    this.hostlistService.obtenerToken() method issue a HTTP call when you subscribe, while the response is awaited [because of the async nature of JS], the other line got executed this.hostlistService.obtenerInmuebles().subscribe.

    You must wait for the response from this.hostlistService.obtenerToken() observable. To do that, you should use observable chaining by using pipe function (see "Piping" topic at https://rxjs-dev.firebaseapp.com/guide/operators) and chaining various operators (as per your need).

    You can do the following -

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpHeaders} from '@angular/common/http';
    import { Inmueble } from '../modelos/inmueble';
    
    @Injectable({
      providedIn: 'root'
    })
    export class HostlistService {
    
        cabecera = {
          'Accept': 'application/json',
          'Authorization': ""
        }
    
        parametros = {
          'grant_type':'client_credentials',
          'client_id': 1,
          'client_secret': 'clientSecret'
        }
    
    
      constructor(public http: HttpClient) {
    
      }
    
    
      obtenerToken(){
        return this.http.post<any>('URL',this.parametros);    
      }
    
    
      obtenerInmuebles(resultToken){
        console.log("Authorization-----------_>"+this.cabecera.Authorization);
        this.cabecera.Authorization=resultToken.token_type+" "+resultToken.access_token;
        return this.http.get<any>('URL',{ headers: new HttpHeaders(this.cabecera) });
      }
    
      mostrarCabecera(){
        console.log("CABECERA::::::::"+this.cabecera.Authorization);
      }
    
    }
    
    import { Component, OnInit } from '@angular/core';
    import { HostlistService } from '../servicios/hostlist.service';
    import {$,jQuery} from 'jquery';
    import { Inmueble } from '../modelos/inmueble';
    
    @Component({
      selector: 'app-slider',
      templateUrl: './slider.component.html',
      styleUrls: ['./slider.component.css']
    })
    
    export class SliderComponent implements OnInit {
      inmuebles: Inmueble[] = [];
      i: number=0;
    
      url: string = "http://crm.seaconfiable.com/upload/";
    
      constructor(private hostlistService: HostlistService) { }
      ngOnInit() {
    
        this.hostlistService.obtenerToken()
            .pipe(
              mergeMap(resultToken => this.hostlistService.obtenerInmuebles(resultToken))
            )
            .subscribe(
              result => {
                console.log("INMUEBLES",result.data);
              },error =>{
                console.log(error);
              }
            );    
      }
    }
    

    I have modified your code only. Although there could be a better way to do the same. Hope this helps.

    In the above code, I have used pipe function on this.hostlistService.obtenerToken() and apply mergeMap operator which will ensure to call this.hostlistService.obtenerInmuebles(resultToken)) observable once the response of this.hostlistService.obtenerToken() has been received and this is what we want.

    I would highly recommend checking the following websites to know more about rxjs and various operators -

    https://rxjs-dev.firebaseapp.com/guide/overview https://www.learnrxjs.io/

    Also, you can avoid the explicit call to subscribe() by using async pipe. See the following - https://blog.angularindepth.com/the-best-way-to-unsubscribe-rxjs-observable-in-the-angular-applications-d8f9aa42f6a0

    EDIT 2 [This edit is done to show how to save token in the localStorage [as requested by the user] -

    ngOnInit() {
    
        this.hostlistService.obtenerToken()
            .pipe(
              mergeMap(resultToken => {
                //do whatever you want to do with the token
                //i.e. Save the token in the localstorage like this - 
                localStorage.setItem("token",resultToken);
                return this.hostlistService.obtenerInmuebles(resultToken);
              })
            )
            .subscribe(
              result => {
                console.log("INMUEBLES",result.data);
              },error =>{
                console.log(error);
              }
            );    
      }