Search code examples
javascriptangularasynchronoussubscribe

Angular wait until subscribe is done and give values to other function


i have this following function

file: subcategory.service.ts

getSubCategoriesById(inp_subCatid: String): Observable<any>{
  this.getSubCategoriesList().snapshotChanges().pipe(
    map(changes =>
     changes.map(c =>
      ({ key: c.payload.key, ...c.payload.val() })
     )
    )
  ).subscribe(subCategories => {
    subCategories.filter(function (subCat) {
     return subCat.id == inp_subCatid;
   });
});

and i´m calling the top function in the following file

file: subcategory.page.ts

this.SubCategoryService.getSubCategoriesById(subCatid).subscribe((subCategories: any) => {
  this.subCat = subCategories ;
})

the problem what i got is i´m getting following error message: ERROR TypeError: "this.SubCategoryService.getSubCategorysById(...) is undefined"

i want to get the data when there are loaded from the file "subcategory.service.ts" hope someone can help me.


Solution

  • Your method should be like this:

    getSubCategories(inp_subCatid: string): Observable<any> {
      return this.getSubCategoriesList().snapshotChanges().pipe(
        map(changes => changes.map(c => 
            ({ key: c.payload.key, ...c.payload.val() })
          ).filter((subCat) => subCat.id === inp_subCatid)
        ));
    }
    

    Then you will be able to use like this:

    this.subCategoryService.getSubCategories(subCatid)
      .subscribe(subCategories => this.subCat = subCategories);
    

    If I'm interpreting correclty your methods, it seems to me that you're using firebase... if so, after you call this.yourService.getSubCategories(subCatid) for the first time, your subscription will remain active so that your subcategories will be updated for every change on the database, even if you change subCatid, the previous database query will be alive. To avoid it, I suggest that you take just one emission of snapshotChanges():

    getSubCategories(inp_subCatid: string): Observable<any> {
      return this.getSubCategoriesList().snapshotChanges().pipe(
        // finish the subscription after receiving the first value
        take(1),
        map(changes => changes.map(c => 
            ({ key: c.payload.key, ...c.payload.val() })
          ).filter((subCat) => subCat.id === inp_subCatid)
        ));
    }