0

I want to get a return-value from this asynchronous function exports.getServices. But I just get nothing / null back.

        var http = require("http");
        var mysql = require('mysql');
        var url = require("url");

        var connection = mysql.createConnection({
        ...
        });

        connection.connect();

        exports.getServices = function (){
            connection.query('SELECT DISTINCT SERVICE FROM booking_count', function(err, rows, fields) {
                if (err) throw err;
                var services = new Array();
                for (var i in rows) {
                    services[i] = rows[i].SERVICE;
                }
                return services;
            });
        }

I access this method from another module:

var express = require('express');
var hbs = require('express3-handlebars');

var app = express();
app.engine('html', hbs({defaultLayout: 'layout'}));
app.set('view engine', 'html');
app.set('views', __dirname + '\\views');
app.use(express.bodyParser());

var mysql = require('./mysql');

app.get('/', function(req, res) {
    res.render('index',{title:"Services", services:mysql.getServices()});
});

app.get('/article/:id', function(req, res) {
    var entry = blogEngine.getBlogEntry(req.params.id);
    res.render('article',{title:entry.title, blog:entry});
});

app.listen(3000);

It would be very helpful if you could post a corrected code. Thank you very much in advance!

1 Answers1

3

You don't provide any information about what module implements connection. Also, you don't make totally clear which function [getServices(), or the callback function passed to query()] is not returning anything. However, I will still try to answer your question.

  1. The getServices() function never returns anything -- it just calls query(). So, obviously, you can't expect to get a result like this:

    var result = getServices(...);

  2. The callback function does return a value, but since it is the query() function that is calling it, there is no way for you to get that return value. Also, query() is probably ignoring any return value, anyway.

To fix this, you need to pass to getServices() your own callback function to receive the results. So, your implementation should look more like this:

connection.connect();

exports.getServices = function (next) {
    connection.query('SELECT DISTINCT SERVICE FROM booking_count', function(err, rows, fields) {
        if (err) throw err;
        var services = new Array();
        for (var i in rows) {
            services[i] = rows[i].SERVICE;
        }
        next(services);
    });
}

However, you should figure out if throwing an error (in the original callback, when there is an error) will cause problems (like causing your server to crash). You may want to do something else instead:

connection.connect();

exports.getServices = function (next) {
    connection.query('SELECT DISTINCT SERVICE FROM booking_count', function(err, rows, fields) {
        if (err) return next(err); // Pass err to next, and immediately return.
        var services = new Array();
        for (var i in rows) {
            services[i] = rows[i].SERVICE;
        }
        next(null, services); // Pass result to next (with no error).
    });
}

Welcome to the world of asynchronous functional programming!

cybersam
  • 63,203
  • 6
  • 53
  • 76
  • Thank you very much. Could you post how the function, which are passed as callback method "next", should look like? And also which method i call in the other module? – user3494729 Apr 04 '14 at 10:07