Giles Taylor Giles Taylor - 4 months ago 7
Ajax Question

Delaying a JQuery function until another JQuery function has run

I have a (slightly convoluted) set of functions to populate the DOM with info. To begin, I make a call to a personalised JSON with a list of movies, which in turn calls on the OMDb API for each movie to grab the info that I want. I want to then take pieces of this information (in this instance, genre) in order to populate a filter menu (click "comedy" if you just want to see comedies, etc.).

I want to create an object containing the genres and use that to populate my menu. My problem is that the menu begins populating while my initial AJAX call is still working. I've had a go with "when" but don't seem to be getting it right.

How can I set an instruction that only populates the genre menu once all of the movie info is sourced?

My (abridged) code so far:

$(function(){
getMovieList();
});

function getMovieList() {
$.ajax({
url: "movielist.json",
type: "GET",
dataType: "JSON",
success: function(data) {
$.each(data, function(key, val) {
var title = val.toLowerCase().split(" ").join("+");
getMovieInfo(title);
});
},
complete: function() {
populateGenre(); // not doing what I want....
}
});
}

function getMovieInfo(title) {
$.ajax({
url: "https://www.omdbapi.com/?t=" + title + "&y=&plot=short&r=json",
type: "GET",
crossDomain: true,
dataType: "JSON",
success: function(val) {
if (!val.Error) {
$("#movie-list").append(...);
genre.push(val.Genre);
}
else {console.log(title)} // ... to catch any films not found on OMDb
}
});

function populateGenre() {
console.log(genre);
}


I want this (for the time being) to console log a couple of dud films and then a long, unwieldy array of genres. However, populateGenre() console logs first, while my getMovieList() and getMovieInfo() functions are still working through the long list of movies.

What should I be doing to push back the populateGenre() function? Thanks for your help!

Answer

the complete method on the first ajax call does not wait for the subsequent calls on other threads. You'll need to use the success method of the subsequent calls to know that all data is loaded.

$(function(){
  getMovieList();
});

function getMovieList() {
  $.ajax({
    url: "movielist.json",
    type: "GET",
    dataType: "JSON",
    success: function(data) {
        for(var i=0;i<data.length;i++){
            var title = data[i].toLowerCase().split(" ").join("+");
            if(i == data.length - 1){           
                getMovieInfo(title, true);
            }else{
                getMovieInfo(title, false);
            }
        }
      });
    }
  });
}

function getMovieInfo(title, isLast) {
  $.ajax({
    url: "https://www.omdbapi.com/?t=" + title + "&y=&plot=short&r=json",
    type: "GET",
    crossDomain: true,
    dataType: "JSON",
    success: function(val) {
      if (!val.Error) {
        $("#movie-list").append(...);
        genre.push(val.Genre);
      }
      else {console.log(title)} // ... to catch any films not found on OMDb
      if(isLast){
        populateGenre();
      }
    }
  });

function populateGenre() {
  console.log(genre);
}
Comments