1

I have data from an observable that I am trying to save into a variable for use in the template, I can see the data being returned in an array or objects which I save to this.products within the scope of the observable, however when I check this.products after executing the observable it shows as an empty array. This is the code I am using: In my component:

  title = 'ngProducts';
  newProduct: any;
  products: any = [] ;
  selectedProduct: any;
  // tslint:disable-next-line:variable-name
  constructor(private _httpService: HttpService) {  }
  // tslint:disable-next-line:use-lifecycle-interface
  ngOnInit() {
    this.newProduct = {details: '', category: '', brand: ''};
    // tslint:disable-next-line:no-unused-expression
    this.selectedProduct;
  }
  getProductsFromService() {
    const observable = this._httpService.getProducts();
    // observable.subscribe(data =>  console.log('this is the observable data: ',  data));
    observable.subscribe(data =>  this.products = data);
    console.log('this is after fetching products: ', this.products);
  }

when I console log the data inside the observable I get the array of objects, but when I try saving it to this.products it doesn't save. so the "after fetching" console log just shows an empty array.

Zach Page
  • 11
  • 1
  • The variable `this.products` is assigned asynchronously. It **cannot** be accessed synchronously. Any statements that depend on it (like the `console.log`) must be inside the subscription. – ruth Oct 04 '20 at 19:06
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – jonrsharpe Oct 04 '20 at 19:07
  • FYI you should *not* have that many line-disabled rules; write the code the rule wants (lifecycle interface, unused expression) or configure it correctly for what you want to write (variable name). – jonrsharpe Oct 04 '20 at 19:08

2 Answers2

1

the value of an observable returns in the subscription async, and you tried to access it before the value returned. To console log "after fetching value", move it inside the subscription.

getProductsFromService() {
    const observable = this._httpService.getProducts();
    observable.subscribe(data => {
      this.products = data,
      console.log('this is after fetching products: ', this.products);
    });
  }
IamFlok
  • 64
  • 4
0

An observable is asynchronous, which means that the execution of code inside the subscribe() only runs AFTER the HTTP call is completed, while the console.log below that runs immediately. This means that the line this.products = data line would not have run before the console.log is executed.

Code looks fine other than that so what problem are you running into? Are you getting an error because you are expecting products on the frontend? You could always add a *ngIf="products.length>0" to frontend to fix that.

Pharcyde
  • 173
  • 5
  • I guess I need to see if my template pulls the products then, I thought I wasn't getting any products because of the empty array for this.products. I will update after I've tried that. – Zach Page Oct 04 '20 at 20:40