Home > OS >  How do I delete an image from disk when I delete the publication that contained it?
How do I delete an image from disk when I delete the publication that contained it?

Time:05-02

Maybe the question is not very clear, so I will explain it better. I have created an application where I can create articles that have a title, content and an image. The image is uploaded with multer to the root folder in a directory called ../frontend/public/uploads/post. As I create posts, the images uploaded with these posts are saved in this folder. The problem is that when I delete the post, the image is not deleted with everything else in the post, but it remains in the same folder. Over time, this can become problematic, as the number of images keeps increasing during the lifetime of the application.

That's what I've tried so far, in the image deletion controller, I added this fs.unlinkmethod, but it doesn't work.

const token = req.cookies.jwt;
const decoded = jwtAuth.verify(token, process.env.TOKEN_SECRET);
const userId = decoded.id;

const { id } = req.params;

const user = await User.findByPk(userId);

try {

    await Post.findOne({
        where: { id: id }
    }).then((postFind) => {
        if (!postFind) return res.status(404).json('Utilisateur non trouvé.');
        
        if (postFind.UserId !== user.id && postFind.UserId !== user.isAdmin === true) return res.status(401).json('Vous ne pouvez pas supprimer cette publication.')

        //Si le UserId correspond à celui de la sauce supprimer de la db
        const filename = postFind.attachment.split(`/../frontend/public/uploads/post/`)[1];
        fs.unlink(`post/${filename}`, () => {
            console.log("test", filename);
            Post.destroy({ where: { id: postFind.id } })
                .then((post) => {
                    if (post === 0) throw new RequestError("Ce contenu n'existe pas !")

                    res.status(200).json('Ce contenu a été suppirmé avec succès !')
                })
                .catch(err => {
                    next(err)
                })
        })

How do I delete an image from disk when I delete the database image? Basically, when I delete a UI image, I want it to be deleted from disk as well.

Multer middleware configuration:

 const multer = require("multer");
    const MIME_TYPES = {
        'image/jpg': 'jpg',
        'image/jpeg': 'jpg',
        'image/png': 'png',
        'image/gif': 'gif'
    
    };
    const imageFilter = (req, file, cb) => {
        if (file.mimetype.startsWith("image")) {
            cb(null, true);
        } else {
            cb("Veuillez télécharger uniquement des images.", false);
        }
    };
    const storage = multer.diskStorage({
        destination: (req, file, cb) => {
            let directory = "";
            directory = "profil" ? "/profil" : "",
                directory = "post" ? "/post" : "";
    
            cb(null, `../frontend/public/uploads/${directory}`);
        },
        filename: (req, file, cb) => {
            let extension = MIME_TYPES[file.mimetype];
            let fileName = "";
            fileName = "profil" ? "profil" : file.originalname;
            fileName = "post" ? "post"   "."   extension : file.originalname   "."   extension;
            cb(null, `${Date.now()}_${fileName}`);
        },
    });
    module.exports = multer({ storage: storage, fileFilter: imageFilter });

The route to delete the image:

router.delete('/:id', PostController.deletePost);

Path Access

app.use('../frontend/public/uploads/post', express.static(path.join('../frontend/public/uploads/post')));

CodePudding user response:

Use path.resolve() to create an absolute path that fs.unlink() can handle.

Also, not using async/await consistently in your request handler is a wasted opportunity.

const fs = require('fs').promises;
const path = require('path');

async (req, res, next) => {
    try {
        const { id } = req.params;
        const token = jwtAuth.verify(req.cookies.jwt, process.env.TOKEN_SECRET);
        const user = await User.findByPk(token.id);

        const post = await Post.findOne({ where: { id: id } });
        if (!post) return res.status(404).json('Utilisateur non trouvé.');
        if (post.UserId !== user.id || !user.isAdmin) return res.status(401).json('Vous ne pouvez pas supprimer cette publication.');

        const result = await Post.destroy({ where: { id: post.id } });
        if (result === 0) throw new RequestError("Ce contenu n'existe pas !")

        const filename = post.attachment.split('/../frontend/public/uploads/post/')[1];
        const filepath = path.resolve(`post/${filename}`)
        await fs.unlink(filepath);

        res.status(200).json('Ce contenu a été suppirmé avec succès !')
    } catch (err) {
        next(err);
    }
}

CodePudding user response:

Basically unlinkSync comes with this facility in nodejs

try {
    //file removed
    var fs = require('fs');
    const directoryPath = join(process.cwd(), '/uploads/');
    fs.unlinkSync(filePath body.name);
} catch(err) {
    console.error(err)
}

Click HERE for reference

  • Related