user9870937
user9870937

Reputation:

Promises: return then() when action inside it is finished

I am using React-Redux-Express, and I'm trying to upload an image with express-fileupload. Here is my logic for uploading images in my Express server:

In my Express route I do this with Sequelize

router.put('/:id', function(req, res, next) {
    models.Projects.update(
        {
            title: req.body.title,
            img: req.body.img,
            description: req.body.description,
        },
        {
            returning: true,
            plain: true,
            where: {
                id: req.params.id,
            },
        }
    )
        .then(() => { 
            if (req.files) {
                req.files.imgFile.mv(toRelative(req.body.img), function(err) { 
                    if (err) {
                        throw new Error('Image saving failed');
                    }
                });
            }
        })
        .then(() => { 
            models.Projects.findById(req.params.id).then((result) => {
                return res.send({
                    Project: result,
                });
            });
        })
        .catch((error) => {
            return res.send(String(error));
        });
});

The problem is that the last then is triggered before req.files.imgFile.mv method is finished moving the image, so the React input component can't find it in the frontend.

Does anyone know how can I create a promise inside the first then, so only when req.files.imgFile.mv is finished moving the image the second is triggered?

Thanks!

Upvotes: 0

Views: 134

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370799

The general idea when you have something callback-based rather than Promise-based is to explicitly construct a Promise so it can be used in the larger Promise chain:

.then(() => { 
  if (!req.files) return; // resolve immediately if there are no files
  return new Promise((resolve, reject) => {
    req.files.imgFile.mv(toRelative(req.body.img), function(err) { 
      if (err) return reject('Image saving failed');
      resolve();
    });
  });
})

But, in this case, it would be easier to omit the callback function to force req.files.imgFile.mv( returns a Promise itself:

.then(() => { 
  // if there are files, then the outer Promise chain will wait
  // for the returned Promise to resolve before continuing with the next .then:
  if (req.files) return req.files.imgFile.mv(toRelative(req.body.img));
})

Upvotes: 5

Related Questions