0

I have a service

export class FoodService {

  private foodUrl: string = "/url/to/data";
  foodList: Food[];

  constructor(private http: Http) { }

  getFoodList(): Observable<Food[]>
  {
    return this.http.get(this.foodUrl)
      .map(response => response.json() as Food[]);
  }
}

which returns an Observable<Food[]>.

In a component I subscribe to the returned Observable. I do this in the ngOnInit()-function:

export class ResultComponent implements OnInit {

  foodList: Food[];

  constructor(private foodService: FoodService) { }

  ngOnInit() {
    this.tags = this.optionService.tags;

    this.foodService.getFoodList()
      .subscribe(list => this.foodList = list);
  }
}

This all works just fine. But now I want to process the foodList and I keep getting errors because at the time of the processing it is still undefined. I even tried passing my processing function as onCompleted parameter in the subscribe call.

Is there a way to wait till the data is fetched?

//edit: In my processing step I loop the Array and count some things. The Error origins from forEach:

 evaluateTags(): void
  {
    this.foodList.forEach(
    //list.forEach(
      food =>
      {
        var count: number = 0;

        this.tags.forEach(
          tag =>
          {
            if (food.tags.includes(tag))
            {
              count++;
            }
          }
        );

        food.hitrate = count / food.tags.length;
      }
    );
  }
liquid.pizza
  • 505
  • 1
  • 10
  • 26
  • What is the code for processing the `foodList`? – Teddy Sterne Mar 27 '17 at 19:09
  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – AT82 Mar 27 '17 at 19:09
  • added the processing step – liquid.pizza Mar 27 '17 at 19:17
  • @AJT_82 Not a duplicate. The said question doesn't contain the solution for observables. – Estus Flask Mar 27 '17 at 19:21
  • @estus It contains all the necessary info. OP is making an async call whether it's an observable or a promise and the tl;dr answer for all is: inside the callback. – eko Mar 27 '17 at 19:24
  • @echonax It doesn't contain sufficient info. Inside which callback? `map`? `do`? `subscribe`? The question contains specific details and it deserves a specific answer. Over-duping is evil. – Estus Flask Mar 27 '17 at 19:27
  • @estus Hmm maybe you are right. Lacked the sense of emphaty there. – eko Mar 27 '17 at 19:29
  • @estus, (wasn't my intention to be evil in any way), maybe we should find a dupe that answers this more *precisely*, there are probably hundreds of these questions here I think :P I'll find one and bookmark it for future use :) – AT82 Mar 27 '17 at 19:32
  • @echonax, write up a self answered question about this issue, as well as the `cannot read blah of undefined` regarding template, it would be really useful here to have one of each :) I assign this honorable task for you, you are very welcome :P No but really, someone really should do this :) – AT82 Mar 27 '17 at 19:36
  • @AJT_82 Thank you :D I'll do it.. – eko Mar 27 '17 at 19:37
  • @echonax Sure, I'll empty the bottle/pint for you while you do the work :D – AT82 Mar 27 '17 at 19:41
  • @AJT_82 lol I'll just edit the last part – eko Mar 27 '17 at 19:42
  • @echonax, well I see that now... and now I look insane, talking to myself about a bottle :D Oh well, better stop chitchatting anyway, before someone has some remarks on that :P – AT82 Mar 27 '17 at 19:45
  • 1
    @AJT_82 agreed good sir : p – eko Mar 27 '17 at 19:46

1 Answers1

2

Just do the processing in the subscribe?

    this.foodService.getFoodList()
    .subscribe(list => {
      this.foodList = list;
      this.evaluateTags();
    });
J0B
  • 1,648
  • 1
  • 12
  • 24