skip to Main Content

I have a problem on my application, it is a social network. The user can create a post with a message and an image, stored in a backend images folder thanks to Multer. I use sequelize and MySql. When I delete a post, the image is indeed deleted in the images folder since I use multer in my post deletion function so everything goes well but when I delete the author, since I go through a relationship between tables so that when I delete a user, their posts are deleted. This works but in this case the images are not deleted from the folder they are stored in, since Multer is not in the loop. How do I get the images to be deleted from the images folder too in this specific case? Thank you for your help !
`

// Template for the Post table

const User = require("../models/User");
const Sequelize = require("sequelize");
const database = require("../config/database");

const Post = database.define("post", {
  content: { type: Sequelize.STRING, allowNull: false },
  image: { type: Sequelize.STRING, allowNull: true },
  likes: { type: Sequelize.INTEGER, allowNull: false, default: 0 },
});
module.exports = Post;

// Relationship with the User table
User.hasMany(Post, { onDelete: "CASCADE", foreignKey: "userId" });
Post.belongsTo(User, { onDelete: "CASCADE" });

`

`

// deletePost function
exports.deleteOnePost = (req, res, next) => {
  Post.findOne({ where: { id: req.params.id } })
    .then((post) => {
      if (!post) {
        return res.status(404).json({
          error: new Error("Post non trouvé !"),
        });
      }
      if (post.userId === req.auth.userId || req.auth.userAdmin) {
        if (post.image) {
          const filename = post.image.split("/images/")[1];
          fs.unlink(`images/${filename}`, () => {});
        }
        Post.destroy({ where: { id: req.params.id } })
          .then(() => res.status(200).json({ message: "Post sans supprimé" }))
          .catch((error) => res.status(400).json({ error }));
      } else {
        return res.status(403).json({
          error: new Error("Requête non autorisée !"),
        });
      }
    })
    .catch((error) => res.status(500).json({ error }));
};

`

3

Answers


  1. Chosen as BEST ANSWER

    @Anatoly Thank you very much for your help, I'm sorry, I'm a beginner, I tried to adapt what you sent me to the method I use. I don't use the async/await method much and don't know much about it. Do you think I'm getting closer to the solution with what i made ? thanks again !

    `
    exports.deleteUser = (req, res, next) => {
      const userId = req.params.id;
    
      User.findOne({ where: { id: userId } }).then((user) => {
        if (!user) {
          return res.status(404).json({
            error: new Error("User not found!"),
          });
        }
      });
      const userPosts = User.getAllPosts();
      const postImages = posts.map((x) => x.image).filter((x) => x);
    
      User.destroy({ where: { id: userId } })
        .then((post) => {
          Post.findOne({ where: { userId } })
            .then((post) => {
              Post.destroy({ where: { userId } }).then((res) =>
                res.status(200).json({
                  message: "User is deleted",
                })
              );
              for (const image of postImages) {
                const filename = image.split("/images/")[1];
                fs.unlink(`images/${filename}`, () => {});
              }
            })
            .catch((error) =>
              res.status(400).json({
                error,
              })
            );
        })
        .catch((error) => res.status(500).json({ error }));
    };
    `
    

  2. I don’t see how Multer is related to a file deletion. It only helps you to store them. Any way you just need to get all posts of a certain user and delete them and a user in a transaction and then delete their images in a cycle:

    // I did not use try/catch for simplicity
    exports.deleteUser = async (req, res, next) => {
       // get the user id somehow (req.params or the request context, for instance)
      const userId = ...
      const user = await User.findById(userId);
      if (!user) {
        return res.status(404).json({
          error: new Error("User not found!"),
        });
      }
      const userPosts = await user.getPosts();
      const postImages = poists.map(x => x.image).filter(x => x);
      // here 'sequelize' is the Sequelize instance, you used to register models
      await sequelize,transaction(async transaction => {
        await Post.destroy({ where: { userId } })
        await User.destroy({ where: { id: userId } })
      });
      for (const image of postImages) {
        const filename = image.split("/images/")[1];
        fs.unlink(`images/${filename}`, () => {});
      }
      res.status(200).json({ message: "User is deleted" }))
    }
    
    Login or Signup to reply.
  3. I come back to put the fonction that works with my method, i often use ".then()" ".catch()", many thanks to Anatoly for helping me to find the solution, here is the result of my work :

    exports.deleteUser = (req, res, next) => {
      User.findOne({ where: { id: req.params.id } })
        .then((user) => {
          if (!user) {
            return res.status(404).json({
              error: new Error("user not found !"),
            });
          }
    
    // I get all the posts of the author
    
          Post.findAll({ where: { userId: req.params.id } })
            .then((posts) => {
    
    // I start a loop in the posts of the author to find the posts with an image
    
              posts.forEach((post) => {
                if (post.image) {
    // I erase the files in the images backend directory
                  const filename = post.image.split("/images/")[1];
                  fs.unlink(`images/${filename}`, () => {});
                }
    // Now i can erase the author
    
                User.destroy({ where: { id: req.params.id } })
                  .then(() =>
                    res.status(200).json({
                      message: "User erased !",
                    })
                  )
                  .catch((error) =>
                    res.status(400).json({
                      error,
                    })
                  );
              });
            })
            .catch((error) =>
              res.status(400).json({
                error,
              })
            );
        })
        .catch((error) => res.status(500).json({ error }));
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search