0

I've recently picked up Node and see that things don't always run sequentially. I'm pretty confused as I'm used to

1) Assignment
2) Print data 

Current I'm running the below function and calling var x = searchForProfessor("prof_name_here");

I then call console.log(x); only to get undefined.

I've been reading about callbacks all over the web and I can't wrap my head around the idea and apply it to this code. Can someone give me some intuition into making the above possible with callbacks?

My Function

var searchForProfessor = function searchForProfessor(teacher_name) {

  google.resultsPerPage = 10
  var nextCounter = 0

  google(teacher_name, function (err, res){

    for (var i = 0; i < res.links.length; ++i) {
      var link = res.links[i];
      if (!link.title.includes('Add') || !link.title.includes('RATINGS') || !link.title.includes("Hint")) {

        request(link, function(err, resp, body){

          if (!err && resp.statusCode == 200) { //If no error is going to happen, then print the data
            var $ = cheerio.load(body);         //Grab the body of data from 'prof_link'
            var overall_rating = $('.breakdown-header .grade').text(); //Get the grade rating from the following classifications text

            if (overall_rating.substr(0,3)) {
              teacher_results.push(prof_name);
            } //End if
          } //End if
        }); //End request
      }//End if for comparisons ||
    } //End For
  }); //End google function
} //End searchForProfessor
Community
  • 1
  • 1
CuriousFellow
  • 225
  • 1
  • 3
  • 14

1 Answers1

2

Because both your google and request functions are asynchronous data returned from those functions will not be immediately available, which is why x

var x = searchForProfessor("prof_name_here");

will always give you undefined when you try to log it.

To mitigate this problem you can pass in functions as parameters to other functions to return that data when it's available.

Here's a small mockup of what's happening with your code complete with how callbacks are used.

async1 mimics a database connection - it returns an object using a key after 1 second by calling the function that's passed into it with the data as its first argument.

function async1(name, callback) {
  var obj = { tea001: { first: 'Dave', last: 'Batman' } };
  setTimeout(function () {
    callback(obj[name]);
  }, 1000);
}

Here we have your searchForProfessor function which accepts a name and a function. It calls async1 with the name, passing in the callback as the second parameter. Note the data which is returned is the returned object data from async1. The callback that was passed into searchForProfessor is used to return that data to...

function searchForProfessor(teacher_name, callback) {
  async1(teacher_name, function (data) {
    callback(data);
  });
}

...this function call to searchForProfessor at which point you can log the data.

searchForProfessor('tea001', function (data) {
  console.log(data);
});

You can see in the demo that the returned data takes around a second to be logged to the console once the code is run.

DEMO

Andy
  • 61,948
  • 13
  • 68
  • 95