0

I wasn't sure how to title this question.

What I am looking to do is grab a large array of movies, filter out only those that have reviews, then sort the reviews by date desc, then trim the list to grab only the latest 11 before setting the first entry to be featured and returning to the model then. With these numerous calls though, I notice some data being jumbled out of order and I believe it's due to all the calls running simultaneously. How can I use promises to structure this to wait for the previous step to complete before proceeding?

getLatestReviews(num) {
    const movieList = this.getMovies();
    const reviewList = movieList.filterBy('review');
    const indexList = this.sortReviewsByDate(reviewList);
    const latestList = this.getSetAmountOfMovies(num, reviewList);
    return this.setFirstReviewToFeatured(latestList);
},


sortReviewsByDate(arr, dir) {
    dir = dir || 'desc';

    return arr.sort(function(a,b) {
        if (dir === 'desc') { 
            return a.review.date < b.review.date;
        } else {
            return a.review.date > b.review.date;
        }
    });
},
getSetAmountOfMovies(num, arr) {
    const movieList = arr ? null : this.getMovies();
    const trimmedList = arr ? arr.slice(0, num) : movieList.slice(0, num);        
    return trimmedList;
},
setFirstReviewToFeatured(arr) {
    arr[0].isFeatured = true;
    return arr;
},

What I'm experience is once I exceed 10 reviews the ordering starts getting out of whack and I believe it's due to the functions not running in a sequence. But I'm not sure how to use promises to ensure one step is complete before running the next.

Yuschick
  • 2,642
  • 7
  • 32
  • 45
  • Do these functions actually return promises? If no, then start with fixing that. – Bergi Jun 17 '16 at 12:42
  • Can you provide an example? – Yuschick Jun 17 '16 at 13:00
  • Not without you showing us what these methods are that you're calling. Or are they standard Ember functions that have documentation somewhere (I don't know Ember)? The question of interest is which of these parts are actually asynchronous - none of those you have shown seem to be (`sort` and `slice` in particular are not for sure) – Bergi Jun 17 '16 at 14:24
  • 1
    I believe the actual problem you are experiencing ("*the ordering starts getting out of whack*") is caused by [the broken comparison function for `sort`](http://stackoverflow.com/q/24080785/1048572) and that there is nothing asynchronous at all. – Bergi Jun 17 '16 at 14:26
  • Thanks, @Bergi that got me on the right track to solving this. – Yuschick Jun 23 '16 at 13:57

1 Answers1

1

You should use promise chain to avoid asynchronous problems :

getLatestReviews(num) {
    return this.getMovies().then(function(movieList) {
       return movieList.filterBy('review');
    }).then(function(reviewList) {
       return //...
    });
},
Raptack
  • 371
  • 1
  • 3
  • 5
  • 1
    You should [chain instead of nest](http://stackoverflow.com/a/22000931/1048572) though – Bergi Jun 17 '16 at 12:56
  • I'm not sure I follow how to implement this. There closing parenthesis on line 3; what is that closing? – Yuschick Jun 17 '16 at 13:19
  • This now creates the following error: TypeError: this.getMovies(...).then is not a function – Yuschick Jun 17 '16 at 13:34
  • Does `this.getMovies(...)` return a promise ? I don't think so, and that's why you get this error. – Raptack Jun 17 '16 at 13:39
  • However, I'm not sure how to return a promise that contains the array. Do I need to import anything from Ember to call new Promise? – Yuschick Jun 17 '16 at 13:57
  • Please see [http://stackoverflow.com/questions/17475657](http://stackoverflow.com/questions/17475657/) – Raptack Jun 17 '16 at 15:16