Reputation: 21
I'm using csvtojson to parse a csv file and want to use it in another module in NodeJS. Pretty sure this is a noob issue in my attempt to learn NodeJS.
function loadPortfolio (portfolio) {
//Converter Class
var Converter = require("./node_modules/csvtojson").Converter;
var converter = new Converter({});
//end_parsed will be emitted once parsing finished
converter.on("end_parsed", function (jsonArray) {
var jsonText = JSON.stringify(jsonArray);
var portfolioObj = JSON.parse(jsonText);
module.exports = loadPortfolio;
});
//read from file
require("fs").createReadStream("./charlesriverexport.csv").pipe(converter);
};
Then in my app.js file:
var loadPortfolio = require('./loadPortfolio');
console.log("Portfolio: ", portfolio);
But, unfortunately the portfolio object comes as undefined.
Any ideas?
Thanks
Upvotes: 1
Views: 6118
Reputation: 2612
You're not calling the loadPortfolio()
function anywhere, you're using the wrong variable name in your app.js
file and your module.exports
can be moved to improve readability
The last part is optional but makes it easy to see whats exported at the top of every file as soon as you open it
NOTE: This only works if you use named function definitions:
function myFunc() {}
and NOT when you store the function in a variable i.e.let myFunc = function() {}
.
Hoisting in JS allows to do this in your module file:
module.exports = loadPortfolio;
function loadPortfolio (portfolio) {
//Converter Class
var Converter = require("./node_modules/csvtojson").Converter;
var converter = new Converter({});
//end_parsed will be emitted once parsing finished
converter.on("end_parsed", function (jsonArray) {
var jsonText = JSON.stringify(jsonArray);
var portfolioObj = JSON.parse(jsonText);
});
//read from file
require("fs").createReadStream("./charlesriverexport.csv").pipe(converter);
};
As functions get loaded before the module is executed, you can export before the function is defined.
then you need to call the function in app.js
var loadPortfolio = require('./loadPortfolio');
var portfolio = loadPortfolio();
console.log("Portfolio: ", portfolio);
Upvotes: 1
Reputation: 3144
Your exported module has to be a function that takes a callback as its parameter. The exported function will supply the callback with the data that is generated asynchronously.
var fs = require('fs');
var Converter = require('./node_modules/csvtojson').Converter;
module.exports = function loadPortfolio (callback) {
var converter = new Converter({});
fs.createReadStream('./charlesriverexport.csv').pipe(converter);
converter.on('end_parsed', function (jsonArray) {
var jsonText = JSON.stringify(jsonArray);
var portfolioObj = JSON.parse(jsonText);
callback(portfolioObj);
});
};
And in the file where you use this module:
var loadPortfolio = require('./loadPortfolio');
loadPortfolio(function(portfolioObj) {
console.log(typeof portfolioObj); // => 'object'
});
Edit: if you want to use the asynchronously fetched portfolioObj
outside of the callback context of loadPortfolio
you have to set an undefined variable then assign it within the callback.
//set undefined variable
var portfolio;
//import your function
require('./loadPortfolio')(function(portfolioObj) {
//assign the global variable a value
portfolio = portfolioObj;
//when doSomething runs portfolio is guaranteed to be defined
doSomething();
});
//see the problem with calling doSomething outside the callback?
doSomething(); // => 'undefined'
function doSomething() {
console.log(typeof portfolio); // => 'object'
}
A neater way to do this is with promises, however.
Upvotes: 2