-1

I'm having trouble returning data that I received from an httpClient get method in angular. I'm getting all of the objects from the DB and I implement an if statement to return an array with some of the objects.

All of the following code is in a service.ts file

getRecipes():Observable<Recipe[]> {
      return this.http.get(this.baseURL + 'recipes') as Observable<Recipe[]>
    }

getRecipesByTag(tag:string):Recipe[]|void{
    let possibleRecipesArr:Recipe[] = []
    this.getRecipes().subscribe((data:Recipe[])=>{
      data.forEach((rcp:Recipe)=>{
        if(rcp.tags.includes(tag)){
          possibleRecipesArr.push(rcp)
        }
      })
      console.log(possibleRecipesArr);
      return possibleRecipesArr
    })
  }

for testing purposes I'm calling the function from the constructor

console.log(this.getRecipesByTag('quick'));

the following is the console output enter image description here

in the console you can see undefined and then the returned object. when I comment out "console.log(possibleRecipesArr);" all I can see in the console is undefined -> therefore we can assume that the undefined came from the function return and not the console.log(possibleRecipesArr)

  1. why is my return statement returning undefined when clearly the variable "possibleRecipesArr" contains the desired object? (as I can see in the console)
  2. why is the return statement being printed out to the console before the console.log(possibleRecipesArr)?

p.s I tried to add casting to the return statement but it didn't make a difference

return possibleRecipesArr as Recipe[]
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437

1 Answers1

1
  1. Obviously console output from console.log(this.getRecipesByTag('quick')) is undefined because function getRecipesByTag has no return statement.

  2. Because arrow function in subscriber is executed asynchronously, after http get request is performed.

Solution is to not subscribe in service. Return Observable of filtered data from service functions. Use pipe method and map function among others from rxjs library to perform operations on fetched data.

Do subscribe in component or, even better, use async pipe in component template.

p.s. Type casting has no impact to result at runtime, it`s pure Typescript construct that is removed by transpiler.