Chris Walker
Chris Walker

Reputation: 75

Node.js + Express - Callbacks returning undefined before Complete

so I'm having real trouble with this - been stuck on it for weeks.

My first function queries a MySQL database and returns a response, which then gets processed in my second function.

The issue is that JS is single-threaded and I can't figure out how to get it to run in the order I want:

  1. Function 1 is fired.
  2. The function fetches the DB response and is then processed.
  3. The reponse is handed to function 2, which then does more processing.

However at the moment, the program jumps straight to function two without allowing time for the query, and the function ends up returning 'undefined'.

var test = functionOne (functionTwo);   
console.log(test);    //returning 'undefined'

function functionOne(callback) {  
            //QUERY TAKES A LONG TIME
            client.query("[QUERY]", function(err, result) {
                    callback(null, result);
            });
}

function functionTwo(err, result) {
           //More processing - slightly slow
           return result;
}

EDIT:

Here is the full file.

    var client = require('./dbHelper');
    var convert = require('./genGIF');
    var exportPPM = require('./makePPM');
    var fs = require('fs');

    module.exports = function() {
            var test = queryDatabase (handleResult);
            console.log("print: " + test);
    }

    function queryDatabase(callback) {    
            //Query our database
            client.query("SHOW TABLES FROM mathsDB", function(err, result) {
                    if (err) {
                            callback(err);
                    }

                    else {                   
                            //Calculate the length of our table and then the last image in the table
                            var currentImage = result[result.length - 1]["Tables_in_mathsDB"];
                            currentImage = currentImage.substring(5);
                            callback(null, currentImage);
                            console.log(currentImage);
                    }
            });
    }

    function handleResult(err, currentImage) {
            fs.stat("./img/image" + currentImage + ".gif", function(err, stat) {
                    if (err==null) {
                            var imageFile = "/img/image" + currentImage + ".gif";
                            return imageFile;
                    }
                    else {
                            //Check if we have a .PPM file made for the image instead, then generate a .GIF
                            fs.stat("./img/image" + currentImage + ".ppm", function(err, stat) {
                                    if (err==null) {
                                            convert.convert("image" + currentImage);
                                            var imageFile = "/img/image" + currentImage + ".gif";
                                            return imageFile;
                                    }

                                    else {
                                            //Generate the .GIF if no .GIF or .PPM already.
                                            exportPPM.make();
                                            convert.convert("image" + currentImage);
                                            var imageFile = "/img/image" + currentImage + ".gif";
                                            return imageFile;
                                    }
                            });
                    }
            });
    }

Upvotes: 3

Views: 1872

Answers (3)

AJS
AJS

Reputation: 2023

this should work:

  //start execution
  functionOne (functionTwo);   


  function functionOne(callback) {  
        //QUERY TAKES A LONG TIME
        client.query("[QUERY]", function(err, result) {
                callback(null, result);
        });
  }

  function functionTwo(err, result) {
       //call function done after long processing is finished with result  
       done(err,result);
  }

  function done(err,result){
       //do your final processing here
       console.log(result);
  }

Upvotes: 1

Akram Saouri
Akram Saouri

Reputation: 1169

just change

client.query("[QUERY]", function(err, result) {
                    callback(null, result);
            });

to :

client.query("[QUERY]", function(err, result) {
                    if( err) return callback(err);
                    return callback(null, result);
            });

Upvotes: 1

jonny
jonny

Reputation: 3098

You're returning your result as the first argument of your callback, but it's expected to be the second - in other words you're populating the err argument with your result, so the argument result will always be undefined.

So change:

function functionOne(callback) {  
            //QUERY TAKES A LONG TIME
            client.query("[QUERY]", function(err, result) {
                    callback(result);
            });
}

To this:

function functionOne(callback) {  
            //QUERY TAKES A LONG TIME
            client.query("[QUERY]", function(err, result) {
                    callback(null, result); // pass it as the second argument
            });
}

That should solve your issue.

Upvotes: 2

Related Questions