Search code examples
node.jsnode-csv-parse

Execute Loop after ReadStream pipe has finished


Not sure if the Title is quite right in this as I'm pretty much stumped (in over my head)...

I'm trying to pull the headers from a csv, as part of an automation test, to the validate those headers. I'm using csv-parse to read the csv file.

Once I've gathered the headers I'm then doing a simple assertion to go through and assert against each one. Using the string values I've entered into my test script.

However currently, the FOR is executing before the csv read and headers have been gathered. I'm not sure how to wait for this to finish before executing the loop.

const fs = require('fs');
const csv = require('csv-parser');
let headerArray = null;
const headerValues = values.split(',');
browser.pause(10000);
fs.createReadStream(""+global.downloadDir + "\\" + fs.readdirSync(global.downloadDir)[0])
  .pipe(csv())
  .on('headers', function (headers) {
    return headerArray = headers
  })
for(var i =0; i<headerValues.length; i++){
 assert.equal(headerValues[i], headerArray[i]);
}


Solution

  • The solution is to run the for loop with your assertions inside the 'headers' event handler, eg:

    var results = [] // we'll collect the rows from the csv into this array
    
    var rs = fs.createReadStream(""+global.downloadDir + "\\" + fs.readdirSync(global.downloadDir)[0])
      .pipe(csv())
      .on('headers', function (headers) {
        try {
          for(var i =0; i<headerValues.length; i++){
            assert.equal(headerValues[i], headers[i]);
          }
        } catch (err) {
          // an assertion failed so let's end
          // the stream (triggering the 'error' event)
          rs.destroy(err)
        }
      }).on('data', function(data) {
        results.push(data)
      }).on('end', function() {
        //
        // the 'end' event will fire when the csv has finished parsing. 
        // so you can do something useful with the `results` array here...
        //
      }).on('error', function(err) {
        // otherwise, the 'error' event will have likely fired.
        console.log('something went wrong:', err)
      })