0

I'm trying to read a TSV data into an array and this async function loads the rows just fine, but the rows.push(row) is still delayed when I'm trying to get the rows outside the function.

Is there a way I can get the row data for use outside this function? I've tried promises, but it seems like they still need to be within an async function.

I'm looping through multiple files and reading the data for each, and I need to wait until all data is loaded to continue, so I don't think it makes sense to wrap everything else in a callback...

const csvToJson = require("csvtojson");
var rows = [];
const getRows = async (fileName) => {
    const csvData = await csvToJson({
      delimiter: "\t",
      trim: true
    }).fromFile(fileName);

    csvData.forEach((row) => {
      rows.push(row);
    });
    return rows;
};

getRows("myfile.tsv");
console.log(rows.length);  // prints 0
setTimeout(function() {
  console.log(rows.length);
}, 2000);                  // prints expected num of rows

// do something else with rows
doSomething(rows);

Alternatively, using callback, but I get a pending promise in return. I know I can resolve it with then, but that doesn't help me outside of then.

const getRows = async (callback, fileName) => {
    const csvData = await csvToJson({
      delimiter: "\t",
      trim: true
    }).fromFile(fileName);

    let rows = [];
    csvData.forEach((row) => {
      rows.push(row);
    });
    return callback(rows);
};

// returns a pending promise
var csvData = getRows(rows => {
  console.log("Rows in callback: " + rows.length);     // expected length
  return rows;
}, "myfile.tsv");

// do something else with data
doSomething(csvData);
R Jackson
  • 105
  • 3
  • 13

3 Answers3

0

try this

const csvToJson = require("csvtojson");

const getRows = async (fileName) => {
    const csvData = await csvToJson({
      delimiter: "\t",
      trim: true
    }).fromFile(fileName);
    return csvData;
};

getRows("myfile.tsv").then(data=>{
  console.log(data.length); 
  }
)
Nilesh Patel
  • 3,193
  • 6
  • 12
0

you can do this instead

const csvToJson = require("csvtojson");

const getRows = async (fileName) => {
  const csvData = await csvToJson({
    delimiter: "\t",
    trim: true
  }).fromFile(fileName);

  const rows = [];
  csvData.forEach((row) => {
    rows.push(row);
  });

  return rows;
};

getRows("myfile.tsv").then((rows) => {
  console.log(rows.length);
});
Meslzy
  • 104
  • 1
  • 9
  • Thank you! But `rows` is undefined outside of the `then` function. I need to use it outside of that. That was why I said I couldn't use `then` above. – R Jackson Dec 23 '20 at 16:04
  • so warp it all with an async function that the only thing you can do – Meslzy Dec 23 '20 at 16:28
0

The answer is just to wrap the functions in async and use await. I guess you can't get this data outside of async

async function getTableDetails(paths, rowStart = 2) {
  let tables = {};
  for (var i = 0; i < paths.length; i++) {
    let p = paths[i];
    const getRows = async (fileName) => {
        const csvData = await csvToJson({
          delimiter: "\t",
          trim: true
        }).fromFile(fileName);
        return csvData;
    };
    let rows = await getRows(p);
    tables[p] = { rows: rows };
  }
  return tables;
}

(async function test() {
  let tableDetails = await getTableDetails(fps, rowStart=2);
  console.log(Object.keys(tableDetails));
  doSomething(tableDetails);
})();
R Jackson
  • 105
  • 3
  • 13