0

I am having trouble sending an error to the front end when a csv file is uploaded and the numbers already exist in the database. The backend is logging an error that the primary key value already exist, but the code I have written tells the front end that the file uploaded just fine.

Code snippet:

router.post('/:program/upload', upload.single('testUpload'), (req, res, next) => {
  try {
    CSVtoPSQL(req.params.program, req.file.filename)
    return res.status(201).json({
      message: 'File Uploaded Just fine :)'
    });
  } catch (error) {
    return res.status(500).json({
      message: error
    })
  }
});

const CSVtoPSQL = (program, filePath) => {
  let stream = fs.createReadStream(path.resolve(__dirname, '../files', filePath));
  let csvData = [];
  let csvStream = csv
    .parse({ headers: false })
    .on('error', error => console.error(error))
    .on('data', (data) => {
      csvData.push(data.toString());
    })
    .on('end', () => {
      csvData.forEach(item => {
        queries.upload(program, item)
          .then(() => {
            console.log('QR Code Added: ' + item);
          }).catch((err) => {
            console.log(`oopsie: ${err}`);
          });
      })
    });
  stream.pipe(csvStream);
}

Pretty confident the issue is with my poor understanding of promises.

  • You are always returning a 201 no matter what happened in the CSVtoPSQL function. That is why the frontend always console QR Code Added. What you should do instead is wait for the response of CSVtoPSQL. If the response is ok, then return a 201, if not, return another status code. Then you should manage that status code returned in your frontend so that yo can handle the case in which some index was already in the database. – fjplaurr Jan 26 '21 at 16:51
  • That is exactly right. I wasn't waiting on a promise of the results of CSVtoPSQL. I'm adding my new working code as an answer. – user3421504 Jan 26 '21 at 17:34
  • I am glad it worked :) – fjplaurr Jan 26 '21 at 18:24

1 Answers1

1

As expected, I wasn't handling my promises correctly. I've updated the code a bit and now it responds with 2 arrays of successful uploads and errored uploads.

router.post('/:program/upload', upload.single('testUpload'), async (req, res, next) => {
  try {
    const result = await CSVtoPSQL(req.params.program, req.file.filename)
    return res.status(201).json(result);
  }
  catch (error) {
    return res.status(500).json({
      message: error,
    })
  }
});

const CSVtoPSQL = (program, filePath) => {
  let stream = fs.createReadStream(path.resolve(__dirname, '../files', filePath));
  let csvData = [];

  return new Promise((resolve) => {
    const results = {
      seccess: [],
      error: [],
    }

    let csvStream = csv
      .parse({ headers: false })
      .on('error', error => console.error(error))
      .on('data', (data) => {
        csvData.push(data.toString());
      })
      .on('end', async () => {
        await Promise.all(
          csvData.map(async (item) => {
            try{
              await queries.upload(program, item);
              results.success.push(item);
              console.log('QR Code Added: ' + item);
            }
            catch (error) {
              console.log(`oopsie: ${error}`)
              results.error.push(item);
            }
          })
        )
        resolve(results);
      });
    stream.pipe(csvStream);
  })
}