angularasync-awaitangular2-observables

How to make program wait until observable is executed in Angular


I'm working on an angular project, I have a situation where making a call to backend using an observable to fetch products.

Here is how the code looks like.

getProducts () : Product[] {
this.http.get<[]>(this.m_baseURL+'/products').subscribe(res => {
  console.log(res)
  this.products = res;
});
  return this.products
}

Problem is, the return statement doesn't wait for the above statement to get executed. And in my component, I get an empty array. I checked using console log in both service and component. And it turns out return statement gets executed before observable is done assigning the value.

How do I make it stop until it completes its job, just like async await does. Should I use normal async await instead of observable?

This is my first Angular project, so please pardon me if the question is novice.


Solution

  • Instead of waiting for returns to time some tasks use reactive approach.

    SomeService.ts

    products$: Product[];
    
    getProducts() : Product[] {
       this.products$ = this.http.get<[]>(this.m_baseURL+'/products');
    }
    

    SomeComponents.ts

    filteredProducts: Product[];
    private readonly unsubscribe$ = new Subject();
    
    constructor(private someService: SomeService){}
    
    ngOnInit() {
       this.someService.getProducts();
    
       this.someService.products$.pipe(takeUntil(this.unsubscribe$)).subscribe((products) => {
       this.filteredProducts = products.filter(product => product.id > 0); // look over filtering
    });
    }
    
    ngOnDestroy() {
     this.unsubscribe$.next();
    }
    

    SomeComponent.html

    <div *ngFor="product of filteredProducs">{{ product }}</div>
    

    Many ways to approach this common problem. Many ways to improve it as well. This is one way. I don't know how your filtering works, but if possible I would prefer to use | async pipe to avoid manual subscribing at all and filter with an additional pipe or filter the observable itself.