0

I am having a scenario where I need to call to the multiple HTTP requests but I am unable to synchronize it.

Below is the code for the same. I am unable to set the cartId(commented down below) value from the HTTP service but I am able to get the response from the service(commented down below)

export class ShoppingCartService {

    constructor(private http:HttpClient) { }

    private create() {

        return this.http.post('http://localhost:8090/shoppingcart',{});
    }

    private  getCart(cartId:string):Observable <any>{

        return this.http.get(`http://localhost:8090/shoppingcart/${cartId}`)
        .pipe(map((response)=>{
            return response;
        }));
    }

    private getOrCreateCartId() {
        let cartId = localStorage.getItem('cartId');
        let id;
        if (!cartId) {
            this.create().toPromise().then(result => {
                localStorage.setItem('cartId', result.body.id);
                id = result.body.id;
            });
            return this.getCart(id);
        } else 
        return this.getCart(cartId);
    }

    addToCart(product: Product) {
        let cartId; 
        this.getOrCreateCartId().toPromise().then(response => {
            console.log(response.body.id); //here i am able to print the response
            cartId =  response.body.id;  
        });
        console.log(cartId); //here i am getting the cartId value as the 
        undefined..
    }
}

Please help me to synchronize this I have tried many solutions but nothing is working.

Himanshu Bansal
  • 2,003
  • 1
  • 23
  • 46
Pranav Shukla
  • 11
  • 2
  • 8

2 Answers2

0
export class ShoppingCartService {

    constructor(private http:HttpClient) { }

    private create() {

        return this.http.post('http://localhost:8090/shoppingcart',{});
    }

    private  getCart(cartId:string):Observable <any>{

        return this.http.get(`http://localhost:8090/shoppingcart/${cartId}`)
        .pipe(map((response)=>{
            return response;
        }));
    }

    private async getOrCreateCartId() {
        let cartId = localStorage.getItem('cartId');
        let id;
        if (!cartId) {
            let result = await this.create().toPromise();
            localStorage.setItem('cartId', result.body.id);
            return result.body.id;

        } else 
          return cartId;
    }

    addToCart(product: Product) {
        let cartId; 
        this.getOrCreateCartId().then((id) => {
           // HERE you get your cartId
           console.log("CartId", id);
           this.getCart(id).toPromise().then(response => {
                ... 
                // HERE you get your cart items
           });
        });
        this.getOrCreateCartId().toPromise().then(response => {

        });
        console.log(cartId); //here i am getting the cartId value as the 
        undefined..
    }
}
0

Since httpClient is an asynchronous method hence it waits for the response until it arrives then runs the code inside syncronously. But the code after http.get(or post) runs synchronously. Hence code after http method gets run even when the response has not yet arrived causing the property cartId(in the code) to be undefined.

In order to keep things synchronous you can put them inside the .subscribe() as show below:

  private getOrCreateCartId() {
    let cartId = localStorage.getItem('cartId');
    let id;
    if (!cartId) {
        this.create().toPromise().then(result => {
            localStorage.setItem('cartId', result.body.id);
            id = result.body.id;
            **return this.getCart(id);**
        });

    } else 
        return this.getCart(cartId);
  }

  addToCart(product: Product) {
    let cartId; 
    this.getOrCreateCartId().toPromise().then(response => {
      console.log(response.body.id); //here i am able to print the response
      cartId =  response.body.id;  
      **console.log(cartId);**
     });
  }

Additional info: Promise also works the same way, ie. it also works asnyc way.

thank you, hope it helps

Saurabh Gupta
  • 315
  • 1
  • 5
  • 14