uploaded image being deleted instead of old image

Black Sulfur
Black Sulfur used Ask the Experts™
on
I have a profile photo which the user can update. What SHOULD happen is that when they upload a new photo, the database is updated and the old photo is deleted. However, what is happening is that the database is updated correctly, but the newly uploaded image is deleted meaning there is no image at all now. I also tried deleting the file synchronously using fs.unlinkSync but had the same result.

const multerStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "public/img");
  },
  filename: (req, file, cb) => {
    const ext = file.mimetype.split("/")[1];
    cb(null, `hero-${Date.now()}.${ext}`);
  }
});

// test if uploaded file is an image
const multerFilter = (req, file, cb) => {
  if (file.mimetype.startsWith("image")) {
    cb(null, true);
  } else {
    // throw error here
    cb(console.log("not an image"), false);
  }
};

const upload = multer({
  storage: multerStorage,
  fileFilter: multerFilter
});
exports.uploadUserPhoto = upload.single("bgImg");

Open in new window



exports.updateHeroImg = async (req, res) => {
  const updateId = "5d13b3c6dd57c43828ed5a7a";
  if (req.file) bgImgNew = req.file.filename;
  //find current image name in database
  const hero = await Hero.findById(updateId);
  if (!hero) return;

  // helper function to delete files
  fileHelper.deleteFile("public/img/" + hero.bgImg);

  // set new db record image name
  hero.bgImg = bgImgNew;

  // update database
  const result = await hero.save();
  res.status(200).send("image uploaded");
};

Open in new window

Helper delete function

const fs = require("fs");

const deleteFile = filepath => {
  fs.unlink(filepath, err => {
    if (err) {
      throw err;
    }
  });
};

exports.deleteFile = deleteFile;

Open in new window


My route:

router.post("/", heroController.uploadUserPhoto, heroController.updateHeroImg);

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Multitechnician
Top Expert 2014
Commented:
fs.unlink is asynchronous so fileHelper.deleteFile is also asynchronous

so line 9 use :

await fileHelper.deleteFile("public/img/" + hero.bgImg);

Open in new window


OR

use :
const fs = require("fs");

const deleteFile = filepath => {
  fs.unlinkSync(filepath, err => {
    if (err) {
      throw err;
    }
  });
};

exports.deleteFile = deleteFile;

Open in new window

Author

Commented:
Thanks for that. I am still having the same issue though. I have updated my original question with my upload code using multer. Perhaps the issue is there.

Author

Commented:
I have changed the code to not delete the image and added console log to some of the steps:

exports.updateHeroImg = async (req, res) => {
  const updateId = "5d13b3c6dd57c43828ed5a7a";
  const hero = await Hero.findById(updateId);
  if (!hero) return;

  console.log("title is " + hero.title + " and image is " + hero.bgImg);
 

  if (req.file) bgImgNew = req.file.filename;
  console.log("the newly uploaded file is " + bgImgNew);
  hero.bgImg = bgImgNew;

  const result = await hero.save();
  console.log("updated database");
  res.status(200).send("image uploaded");
};

Open in new window




title is Some title X and image is hero-1565280744900.jpeg
the newly uploaded file is hero-1565280744900.jpeg
updated database

Open in new window


If I remove this line:

hero.bgImg = bgImgNew;

Open in new window


Then the console.log info is correct in that I have 2 different file names. But now the database is not updated. So, at least I managed to pinpoint the line that is causing the issue, now just need to resolve the issue.
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

Commented:
I have found the issue but I don't know why it is an issue.

If I remove this line:

res.status(200).send("image uploaded");

Open in new window


everything works as expected except that I don't get my success message so the user won't actually know that the record was updated and everything went okay.

It seems that the line of code above makes the request happen twice which was why the image was being deleted after being uploaded but why?
leakim971Multitechnician
Top Expert 2014

Commented:
exports.updateHeroImg = async (req, res) => {
  const updateId = "5d13b3c6dd57c43828ed5a7a";
  const hero = await Hero.findById(updateId);
  if (!hero) return;

  console.log("title is " + hero.title + " and image is " + hero.bgImg);
 

  if (req.file) bgImgNew = req.file.filename;
  console.log("the newly uploaded file is " + bgImgNew);
  hero.bgImg = bgImgNew;

  const result = await hero.save();
  console.log("updated database");
  res.status(200).send("image uploaded");
};

// let's sasy we're at the last line here
// end of connexion here
// and you did not send back anything to browser
// the conversation with you browser and your server is broken

Open in new window


what about :

exports.updateHeroImg = async (req, res) => {
  const updateId = "5d13b3c6dd57c43828ed5a7a";
  const hero = await Hero.findById(updateId);
  if (!hero) return;

  console.log("title is " + hero.title + " and image is " + hero.bgImg);
 

  if (req.file) bgImgNew = req.file.filename;
  console.log("the newly uploaded file is " + bgImgNew);
  hero.bgImg = bgImgNew;

  const result = await hero.save();
  console.log("updated database");
  
};

res.status(200).send("image upload in progress...");

Open in new window

Author

Commented:
Soooo.. After spending time debugging I finally realised that this has nothing to do with node.js which I initially thought that was where the problem was. It turns out it was on the React side with the Filepond package. I had a callback which sent the request but the package was already sending the same request without me knowing it. That is why it was uploading the file and deleting it straight away. I removed my own callback and now it works fine.

Author

Commented:
Although the answer I accepted wasn't actually the solution to my problem, it is helpful information that I can use going forward, thank you.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial