5

I want to use nodejs to read a file line by line and then when it finishes get the returned result as a json string. I was trying to do like this, but at the end the console.log prints undefined and not the list. I got the list and the end of the promise but how do I return it to the calling function in main.js?

I have my main.js file:

var fct = require('./romlist-parser');

console.log(fct.myfunction());

and the romlist-parser.js has the following content:

var fs = require('fs');
var readline = require('readline');

exports.myfunction = function() {

    var promise = new Promise(function(resolve,reject) {
        var rd = readline.createInterface({
            input: fs.createReadStream('Atari 2600.txt'),
            console: false
        });

        var games = [];

        rd.on('line', function(line) {
            var arr = line.split(";");
            games.push({name:arr[0], title:arr[1]});
        });

        rd.on('close', function() {
            var json = JSON.stringify(games);
            resolve(games);
        });

    });

    promise.then((resolveResult) => {
        console.log(resolveResult);
        return resolveResult;
    });
};
user1864255
  • 105
  • 2
  • 2
  • 6
  • Can you say few words as to why you use `readline`, `stream` and `Promise`? Can't a simple `fs.readFile` do the job in your case? – RaphaMex Apr 11 '18 at 19:56
  • The first console log in this OP prints the value returned by the function. That is undefined since the function doesn't return anything. If you don't subsequently see a result being logged, it may be due to a read error (maybe the file isn't found). You can discover that with `rd.on('error' ...` – danh Apr 11 '18 at 20:31

3 Answers3

2

Try this:

exports.myfunction = function() {

    var promise = new Promise(function(resolve,reject) {

        var games = [];
        var rl = readline('./Atari 2600.txt'); // provide correct file path

        rl.on('line', function (line, lineCount, byteCount) {
            // console.log(lineCount, line, byteCount);
            var arr = line.split(";");
            games.push({name:arr[0], title:arr[1]});
        })
        .on('close', function() {
            var json = JSON.stringify(games);
            resolve(games); // resolve(json); may be?? 
        })
        .on('error', function (e) {
            console.log("error", e);
            // something went wrong
        });
    });

    promise.then((resolveResult) => {
        console.log(resolveResult);
        return resolveResult;
    });
};

P.S. This code can be improved further but for sake of simplicity and your understanding answer is limited to the style/code posted in the post. Else it can vary style to style.

Zeeshan Hassan Memon
  • 8,105
  • 4
  • 43
  • 57
0

I'd move the setup and the variable that accumulates the results into the enclosing scope, then, most importantly, return the promise from the function that creates it. So...

exports.myfunction = function(filename) {
    let games = [];
    let rd = readline.createInterface({
        input: fs.createReadStream(filename),
        console: false
    });

    return new Promise(function(resolve,reject) {
        rd.on('line', function(line) {
            var arr = line.split(";");
            games.push({name:arr[0], title:arr[1]});
        });

        rd.on('close', function() {
            var json = JSON.stringify(games);
            resolve(games);
        });
        // on 'error' call reject(error)
    });
};

// then elsewhere

const fct = require('./romlist-parser');

function someFunction() {
    let promise = fct.myfunction('Atari 2600.txt');
    return promise.then(result => {
        console.log(result);
        return resolveResult
    });
}
danh
  • 62,181
  • 10
  • 95
  • 136
-1

I also needed good way to handle line in large file.

So I made this. You can easily iterate over line by line in file, stream, string, buffer

It also supports reverse mode!

Please try and if you like it, give me a star!

https://github.com/sharpart555/nexline

const nl = nexline({
  input: fs.openSync(path_to_file, 'r'), // input can be file, stream, string and buffer
});

console.log(await nl.next()); // 'foo'
console.log(await nl.next()); // 'bar'
console.log(await nl.next()); // 'baz'
console.log(await nl.next()); // null, If all data is read, then return null
Jin
  • 1