Reputation: 1525
I'm taking my first steps in NodeJS, and I'm having an issue with the async-module. I had the following code which works fine:
var http = require('http');
var fs = require('fs');
var async = require('async');
function load_albums(callback) {
fs.readdir("albums", function(err, content) {
console.log(content);
if(err) {
callback(err);
return;
}
var directories = [];
(function iterator(index) {
if(index == content.length) {
callback(null, directories);
return;
}
fs.stat("albums/" + content[index], function(err, stats) {
if (err) {
callback(err);
}
if(stats.isDirectory()) {
directories.push(content[index]);
}
console.log(index);
iterator(index + 1);
});
})(0);
});
}
function handle_request(request, response) {
load_albums(function(err, albums) {
if (err) {
response.writeHead(503, {"Content-Type": "application/json"});
response.end(JSON.stringify(err) + "\n");
return;
}
var out = { error: null,
data: { albums: albums}};
response.writeHead(200, { "Content-Type" : "application/json" });
response.end(JSON.stringify(out) + "\n");
});
}
var s = http.createServer(handle_request);
s.listen(8080);
This works fine, and gives the expected output:
{"error":null,"data":{"albums":["testdir1","testdir2"]}}
However, I intended to replace the iterator with the async.each function.
I ended up with this:
function load_albums(callback) {
fs.readdir("albums", function(err, content) {
console.log(content);
if(err) {
callback(err);
return;
}
var directories = [];
async.each(content, function(item, callback2) {
fs.stat("albums/" + item, function(err,stats) {
if(stats.isDirectory()) {
directories.push(item);
}
callback2();
});
});
callback(null, directories);
});
}
However, this doesn't seem to work, as "albums" seems to be empty now:
{"error":null,"data":{"albums":[]}}
What am I missing here? I guess it has something to do with calling the fs.stats() function, but I'm unsure about what I'm doing wrong.
Upvotes: 0
Views: 74
Reputation: 10633
As answered by @jfriend00 final callback is third parameter of asyn.each
. Currently this callback is running without waiting for async.each
to complete.
Also you're serving albums for all the request. They should be served on a particular resource URL like /albums
or /albums/
I have made these modifications to the code, now it loads albums on http://localhost:8080/albums
otherwise it returns 'No Content
.
var http = require('http');
var fs = require('fs');
var async = require('async');
function load_albums(loadCompleteCallback) {
fs.readdir("albums", function(err, content) {
console.log(content);
if(err) {
callback(err);
return;
}
var directories = [];
async.each(content, function(item, doneCallback) {
fs.stat("albums/" + item, function(err,stats) {
if(stats.isDirectory()) {
directories.push(item);
}
return doneCallback(err);
});
}
, function (err) {
loadCompleteCallback(err, directories);
});
});
}
function handle_request(request, response) {
console.log("requested path: " + request.url);
if(request.url.match(/^\/albums[\/]?$/) ) {
load_albums(function(err, albums) {
if (err) {
response.writeHead(503, {"Content-Type": "application/json"});
response.end(JSON.stringify(err) + "\n");
return;
}
var out = { error: null,
data: { albums: albums}};
response.writeHead(200, { "Content-Type" : "application/json" });
response.end(JSON.stringify(out) + "\n");
});
} else {
response.writeHead(200, { "Content-Type" : "application/json" });
response.end("No Content\n");
}
}
var s = http.createServer(handle_request);
s.listen(8080);
console.log("server running at : http://localhost:" + 8080);
Upvotes: 1
Reputation: 707158
async.each()
takes three arguments. You are not passing the last one which is the one that tells you when it is done. You also haven't implemented error handling on fs.stat()
. You can change to this:
function load_albums(callback) {
fs.readdir("albums", function(err, content) {
console.log(content);
if(err) {
callback(err);
return;
}
var directories = [];
async.each(content, function(item, callback2) {
fs.stat("albums/" + item, function(err,stats) {
if (!err && stats.isDirectory()) {
directories.push(item);
}
callback2(err);
});
}, function(err) {
callback(err, directories);
});
});
}
Upvotes: 1