0

I've set up a route to upload a .csv file, validate the data received, check that none of the rows exist in the database and finally upload the data once all validation checks have been performed.

Below is the route in question:


...
const Customer = require('../models/Customer');

const fs = require('fs');
const multer = require('multer');
const csv = require('fast-csv');

router.post('/customers/csv', upload.single('file'), async (req, res) => {
    const errors = [];
    const fileRows = [];
    const existRows = [];
    const count = 1;

    fs.createReadStream(req.file.path)
        .pipe(csv.parse({ headers: true }))
        .validate(data =>
            // Data validation for each field...
        )
        .on('error', error => console.error(error))
        .on('data-invalid', (row, rowNumber) => 
            {
                errors.push(`Invalid [rowNumber=${rowNumber}] [row=${JSON.stringify(row)}]`)
                console.log(`Invalid [rowNumber=${rowNumber}] [row=${JSON.stringify(row)}]`)
            }
        )
        .on('data', async function (row) {
            if(await Customer.exists({$or: [
                {srn: row.srn},
                {telephone: row.telephone},
                {claim_id: row.claim_id},
                {receiver_id: row.receiver_id}
            ]})) {
                // This doesn't store data so long as I'm using async/await
                // but I need the await for the mongoose query
                existRows.push(row)  
            } else {
                fileRows.push(row) // This doesnt work so long as I'm using async
            }
            count++;
        })
        .on('end', (rowCount) => {
            fs.unlinkSync(req.file.path);

            if(errors.length !== 0) {
                req.flash(
                    'error_msg', 
                    `Upload failed! Parsed ${rowCount} rows with ${errors.length} bad rows at rows:`
                )
                return res.redirect('/admin/customers/csv')
            } 

            if(existRows.length !== 0) {
                req.flash(
                    'error_msg',
                    `Error: ${existRows.length} rows already exist. Kindly edit and try again.`
                )
                return res.redirect('/admin/customers/csv')
            }

            fileRows.forEach(async customer => {
               //Execute an insertion or save
            })
        })
    })

Unfortunately it would seem I can't access the existRows or fileRows data I store outside of the on.('data'...) portion and use them in the on.('end'...) portion.

I assume it must be an issue with how I've set up my async/await in there?

sylvahman
  • 13
  • 3

0 Answers0