willyb321 willyb321 - 2 months ago 6
Javascript Question

How to get a variable that is nested inside another function

So, I have this code:

function readLineMemory() {
loadFile = dialog.showOpenDialog({properties: ['openFile']});
console.log(loadFile);
var lr = new LineByLineReader(loadFile[0]);
lr.on('error', err => {
return console.log(err);
});
lr.on('line', function (line) { // called every line
// var html = '';
const lineParse = JSON.parse(line);
JSONParsed.push(lineParse);
let htmlTabled = tableify(lineParse) + '<hr>';
html = html + htmlTabled;
});
lr.on('end', function () { // called when file is read fully
html = 'data:text/html,' + html;
})} return html


However, when I try to return the html value, it just returns undefined. I have been banging my head on the wall for a while with this, and I just cannot figure out what I am doing wrong. As far as I'm aware, the code isn't async. The html value should actually be a string of html code that I am using in another function.

Answer

The callbacks are asynchronous, according to what I see in the code here: https://github.com/Osterjour/line-by-line/blob/master/line-by-line.js#L43-L45

setImmediate(function () {
    self._initStream();
});

The parsing doesn't start until the next "tick" in the event loop. Generally, it's good to assume that most callbacks take place asynchronously. You'll want to convert your function to also be asynchronous:

function readLineMemory(cb) {
  let html = '';
  const loadFile = dialog.showOpenDialog({properties: ['openFile']});
  const lr = new LineByLineReader(loadFile[0]);
  lr.on('error', err => {
      cb(err);
    })
    .on('line', function (line) { // called every line
      const lineParse = JSON.parse(line);
      JSONParsed.push(lineParse);
      let htmlTabled = tableify(lineParse) + '<hr>';
      html = html + htmlTabled;
    })
    .on('end', function () { // called when file is read fully
      html = 'data:text/html,' + html;
      cb(null, html);
    });
}

(or IMO even better with promises):

function readLineMemory() {
  return new Promise(function (resolve, reject) {
    let html = '';
    const loadFile = dialog.showOpenDialog({properties: ['openFile']});
    const lr = new LineByLineReader(loadFile[0]);
    lr.on('error', err => {
        reject(err);
      })
      .on('line', function (line) { // called every line
        const lineParse = JSON.parse(line);
        JSONParsed.push(lineParse);
        let htmlTabled = tableify(lineParse) + '<hr>';
        html = html + htmlTabled;
      })
      .on('end', function () { // called when file is read fully
        html = 'data:text/html,' + html;
        resolve(html);
      });
  });
}