nodejs & mongodb refresh bug?
Problem
I am new to nodejs but I did get something to work last night with mongodb on a IIS server with iisnode. :)
But I am wondering over one thing which seems to be a Refresh bug or something. When I go to "http://localhost/mongo.js" in my browser the results will just be "[]" the first time. If I hit refresh the results will be what I expected (an json array with persons). Dosen't this seems wrong?
Let's say now I do it with a query, "http://localhost/mongo.js?name=Daniel", and get all Persons with the name Daniel. The response the first time will be "all the persons" because that's what we asked for above, and when I hit refresh the results will be all the Persons named Daniel. Why is this happening? It seems that the server cached the query's i've made, and I don't want to hit refresh everytime to get the correct results.
This is my code I am using: (also available here http://pastebin.com/PnVfrQmh)
/* GLOBALS
----------------------------------------------------------------------*/
var rdata = [];
/* SERVER SETTINGS
----------------------------------------------------------------------*/
//load http module to ceate an http server.
var http = require('http');
var url = require('url');
//configure to respond http server with message
http.createServer(function (request, response) {
//request name parameter
var url_parts = url.parse(request.url, true);
var query = url_parts.query;
//do the mongo
var mongo = require('mongodb');
var db = new mongo.Db('nodedb', new mongo.Server('localhost', 27017, {}), {});
db.open(function() {
db.collection('Persons', function(err, collection) {
var cursor = collection.find(query);
cursor.each(function(err, doc) {
if(doc) {
rdata.push(doc);
}
});
});
});
//write what type of response
response.writeHead(200, {'Content-Type': 'application/json;charset=utf-8'});
//return data json array
response.end(JSON.stringify(rdata));
//clear rdata
rdata = [];
}).listen(process.env.PORT);
Solution
You have to remember that you are always in an async world with node.js. This caught me out as well coming from a more sync background.
What is happening here is your response is returning before the logic is run. This is because when you call db.open(function() {
this goes on the event loop and returns. This is non-blocking so the next line of code that runs is response.writeHead(200, {'Content-Type': 'application/json;charset=utf-8'});
. Then the callback for db.open
is called, sometime in the future.
In order to correct this. return the response after the cursor.each(function(err, doc) {
loop is finished.
Hope this helps.
Discussion
View additional discussion.