-2

I have an array of movies with IDs, but without ratings. I want to query a movie database to get the ratings for each movie, so I iterate over each object using fetch(url) to query the API and then use .then(function(response) { add_rating_to_specific_movie}).

The problem is, .then is an async response, and I have no way of knowing which movie has returned a rating value so that I can mutate the correct movie object with the rating. And I can't create a new array with the returned values, because some movies will return status: movies not found, and I have no way of knowing which movies are unrated.

Could use some guidance on a good algorithm for using promises here. Thanks!

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Yoni
  • 11
  • 1
  • 4

1 Answers1

0

You don't show your actual code for how you are iterating the array of movies so we can only provide a conceptual answer (next time show your actual iteration code please). But, in concept, you just use a function to pass the index or object separately for each array element and then you can access that index or object in the .then() handler. In this case, if you use .forEach() to iterate your array, the object from your array of objects that you are iterating and the index of that object are both passed to you in a function that will be uniquely available for each separate request.

For example, here's one concept that would work:

var movies = [....];   // array of movie objects
movies.forEach(function(movie, index) {
     // construct url for this movie
     fetch(movieURL).then(function(data) {
        // use the data to set the rating on movie
        movie.rating = ...
     });
});

If you want to use promises to know when all the requests are done, you can do this using Promise.all():

var movies = [....];   // array of movie objects
Promise.all(movies.map(function(movie, index) {
     // construct url for this movie
     return fetch(movieURL).then(function(data) {
        // use the data to set the rating on movie
        movie.rating = ...
     });
})).then(function() {
    // all ratings updated now
});
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Rather use `.map()` so that you can right apply `Promise.all` on it… – Bergi Sep 13 '15 at 16:14
  • @Bergi - it wasn't clear the OP was asking for that, but I added that as an option. – jfriend00 Sep 13 '15 at 16:24
  • Yeah, it's not clear what OP needs, I wonder why you answered at all… :-) – Bergi Sep 13 '15 at 16:26
  • @Bergi - it's not that unclear. Array of movies without ratings. `fetch()` on each movie to get rating, update movie object in the array with the returned rating. While the OP could have made things easier, the info is there to see what they're asking. I did suggest to the OP that they should include the code they have so far next time. – jfriend00 Sep 13 '15 at 16:28
  • @Yoni - did this answer your question? – jfriend00 Sep 14 '15 at 03:18
  • @jfriend00 - In your first solution - the engine would iterate over each movie, calling fetch(url) on each. When 'then' is called, at some later asynchronous time, I would think it wouldn't have access to the movie object (very well may be mistaken). Also, would upvote your answer, but don't have enough reputation yet :( – Yoni Sep 14 '15 at 08:52
  • @Yoni - `movie` is still in scope in the `fetch()` callback. It is in a parent scope which is accessible. If this answers your question, then even with no reputation, you can still accept an answer (click green checkmark to the left of an answer) to indicate to the community that it was the best answer and that it answered your question. That will also earn you some reputation. – jfriend00 Sep 14 '15 at 23:08