0

I am trying to upload multiple images and such goal. I've created an array called response where I push any response from the query call but I get an empty array in the end.

router.post('/:user', upload.array('media', 100), async (req, res) => {
    const {user} = req.params;
    const files = req.files;
    if (!files) return res.status(400).json({errors: {msg: 'File missing'}});
    var response = [];
    const sql = 'INSERT INTO media (path, user, verified) VALUES (?,?,?)';
    for (var file of files) {
        await connection.query(sql, [file.originalname, user, 0], async (err, result) => {
            if (err) {
                response.push(err);
            } else {
                response.push({path: file.originalname, user: user});
            }
        });
    }
    await res.json(response);
});
josh
  • 87
  • 6

1 Answers1

0

Because mysql-node doesn't support Promise out of the box, and connection.query is callback based. So you need to Promisify or manually make the .query a promise.

const util = require('util');

router.post('/:user', upload.array('media', 100), async (req, res) => {
  const {user} = req.params;
  const files = req.files;
  if (!files) return res.status(400).json({errors: {msg: 'File missing'}});
  var response = [];
  const sql = 'INSERT INTO media (path, user, verified) VALUES (?,?,?)';
  const promiseQuery = util.promisify(connection.query);
  for (var file of files) {  
    try{
      await promiseQuery(sql, [file.originalname, user, 0]);
      response.push({path: file.originalname, user: user})
    }catch(err){
      response.push(err);
    }
  }
  await res.json(response);
});

But as the inserts are not dependant it is better to push it to a promise and call a Promise.all. Check this out for hints Wait until all promises complete even if some rejected


EDIT: adding the POC that I used to test the code.

const multer = require('multer');
const util = require('util');
const bodyParser = require('body-parser');
const express = require('express');
const fs = require('fs');
const app = express();

app.use(
  bodyParser.urlencoded({
    extended: false
  })
);
var upload = multer({ dest: 'uploads/' });
app.use(bodyParser.json());
const somePromise = util.promisify(fs.appendFile);

app.post('/:user', upload.array('media', 100), async (req, res) => {
  const { user } = req.params;
  const files = req.files;
  if (!files) return res.status(400).json({ errors: { msg: 'File missing' } });

  var response = [];
  for (var file of files) {
    const sql = `INSERT INTO media (path, user, verified) VALUES (${file.originalname}, ${user}, 0)\n`;
    try {
      await somePromise('somefile.txt', sql);
      response.push({ path: file.originalname, user: user });
    } catch (err) {
      response.push(err);
    }
  }
  await res.json(response);
});

// the port where the application run
const port = process.env.PORT || 8080;
app.listen(port, () => console.log(`Listening on port ${port}...`));

after hitting it http://localhost:8080/user with Postman, here is the output:

[
    {
        "path": "Screenshot 2019-12-22 at 4.17.34 AM.png",
        "user": "user"
    },
    {
        "path": "Screenshot 2019-12-22 at 4.17.34 AM.png",
        "user": "user"
    }
]
Aritra Chakraborty
  • 12,123
  • 3
  • 26
  • 35