Reputation: 401
Let's say I have an Express app and I want to display something I get from a database. I have a file that contains this (using node-mysql for database interaction)
exports.getData = function() {
connection.query('SELECT * FROM table', function (error, rows, fields) {
return rows[0];
});
}
I'd love to be able to call that and have the data to pass on to the template language. However, it doesn't work that way, because (I think) the call back doesn't return until after the function has exited, resulting in getData returning undefined.
I must be missing some important "aha" moment about callbacks. If I want to interact with the database, am I forced to do all the logic in routes/index.js (the controller for the page I'm serving) and finally render the page at the bottom of a series of callbacks?
Upvotes: 2
Views: 792
Reputation: 11
you may want to check out the async module: https://github.com/caolan/async
Here is an example where I make a few data calls in parallel before rendering the view.
var async = require('async'),
example = require('example-api-client');
module.exports = function(app){
app.get('/example', function(req, res){
async.parallel(
{
apples: function(cb){
example.getData('apples', cb);
},
oranges: function(cb){
example.getData('oranges', cb);
}
},
function(err, results){
//TODO: handle errors
res.render('example', results);
}
);
});
};
Upvotes: 0
Reputation: 2022
You can use "promise" in this link can to find more information
Promises provide a compelling alternative to raw callbacks when dealing with asynchronous code. Unfortunately, promises can be confusing and perhaps you’ve written them off. However, significant work has been done to bring out the essential beauty of promises in a way that is interoperable and verifiable. The result is Promises/A+, a specification that is making its way into promise libraries and even the DOM.
var promise = (connection.query('SELECT * FROM table')
promise.then(function (somedata){renderPage(rows[0])};)
Upvotes: 0
Reputation: 984
Something like this is probably what you are looking for. Call another function in your query callback.
exports.getData = function() {
connection.query('SELECT * FROM table', function (error, rows, fields) {
renderPage(rows[0]);
});
}
function renderPage(data) {
app.render('page', {
"data": data
}
}
Upvotes: 0
Reputation: 490143
Pass in a callback as an argument to getData()
that is exported...
exports.getData = function(callback) {
connection.query('SELECT * FROM table', function (error, rows, fields) {
callback(error, rows[0]);
});
}
Then, you can do...
var data = require("data");
data.getData(function(error, firstRow) { });
Tadman made a good suggestion of following the convention that the first argument is for the error. Doing it this way, we can propagate the error information.
Upvotes: 3