I haven't been able to test your code myself, but from reading your code, you are running into two problems, which go hand in hand with your questions.
Firstly, you are running into the typical problem most people run into when starting out with nodejs. You are calling an asynchronous function, synchronously. That's why it's printing undefined the first two times, you are printing the results of calling users. Since users hasn't finished running yet, it's value is undefined. You should implement the library.js
function users with a callback. For example:
exports.users = function (callback) {
csv.fromPath("users.csv", {headers: true})
.on("data",function(data){
DataToBeReturned.push(data);
})
.on("end",function(){
console.log(DataToBeReturned.length);
return callback(null, DataToBeReturned);
});
};
Then in app.js
you would implement this to work with callbacks.
var csv = require("fast-csv");
// err is just a nodejs convention, if you add error checking to users,
// instead of throwing an error, you would pass it back as the first agrument
// to the callback
mylibrary.users(function(err, users) {
console.log(users);
});
mylibrary.users(function(err, users) {
console.log(users);
});
Secondly, you are referring to a global variable from your users
function. That is you print out 3 and 4. Both calls are acting on the variable at once. When the first call finishes and returns the value, the second call had already also modified the array. So, you want to move the array declaration instead of your function, so only code in there has access to it.
exports.users = function () {
var DataToBeReturned = [];
// the rest of your code.
};
EDIT: the code inside of modules is cached, so it is only executed once. Then each script that refers to it is simply returned that copy. If you need to only read the csv once, use this to your advantage.
var DataToBeReturned = [];
var called = false;
function read(callback) {
if (called) {
process.nextTick(function() {
return callback(null, DataToBeReturned);
});
return;
} else {
called = true;
csv.fromPath("users.csv", {headers: true})
.on("data",function(data){
DataToBeReturned.push(data);
})
.on("end",function(){
console.log(DataToBeReturned.length);
return callback(null, DataToBeReturned);
});
}
};
exports.users = function(callback) {
return read(callback);
};
The process.nextTick part is important, more information on how it works can be found here in the documentation.