Home > other >  How can I remove bookmarked posts of user (1) from user (2) tab after user (1) deletes his account?
How can I remove bookmarked posts of user (1) from user (2) tab after user (1) deletes his account?

Time:12-08

After creating a node.js, express, mongoDb REST api for a social media web app with almost all basic social media actions (login, signup, add a post, delete a post, delete account, follow users ...), I'm currently facing a problem, where after implementing bookmarking a post feature, I'm unable to come up with a solution to remove a bookmarked post from another user's bookmarked posts page, after the first user deletes his account. I'll provide my code below: (P. S. Bookmarks is an array inside User model. I'd also like to mention the steps that I initially intended for the task:

  1. Get current user by ID

  2. Then get all posts created by this user, which returns an array, so I mapped it to get each Posts id

  3. After that I fetched all users accross the app, and initially intended to compare the posts that live inside bookmarks array inside each user to the posts that the current user have created. Then I'd pull these same posts out of the bookmarks array from each of these users. --> I think the logic that I've analyzed is maintainable, but it's just not working with me. This is the Code below:

    export const deleteUser = async (req, res) => { try {

     let user = await User.findById(req.params.userId)
    
         const userPosts = await Post.find({ creatorId: user._id })
    
         const allUsers = await User.find()
         const myPostsIds = userPosts.map((post) => post._id.toString())
    

//This is the section I've implemented for my task, but obviously something isn't right

        await Promise.all(
            myPostsIds.forEach((id) =>
                allUsers.map((user) => {
                    user.bookmarks.includes(id) &&
                        user.updateOne({ $pull: { bookmarks: id } })
                })
            )
        )

        await Post.deleteMany({ creatorId: user._id })
        await user.remove()
        
        res.status(200).json({
            message: "Account has been deleted successfully!",
        })
    
} catch (err) {
    errorHandler(res, err)
}

}

CodePudding user response:

As mentioned in my comments, the value you pass to Promise.all is no array of Promise/array of async functions.

The 2nd error is inside the (currently) forEach function at the .map() you are not returning anything in the map-call.

So this should do it:

// first convert all ids to a promise
await Promise.all(myPostsIds.map(id => new Promise(resolve => {
  // during this, await every test and update
  return Promise.all(allUsers.map(user => new Promise(resolve => {
    // if it includes the id, cast the update and then resolve
    if (user.bookmarks.includes(id)) {
      // if found, resolve the promise for this user after the change
      user.updateOne({ $pull: { bookmarks: id } }).then(resolve)
    } else { 
      // resolve directly if not found.
      resolve()
    }
  // when all users are done for this id, resolve the Promise for the given id
  }))).then(resolve)
})))

An easier to read and shorter method would be:

for (const id of myPostIds) {
  for (const user of allUsers) {
    if (user.bookmarks && user.bookmarks.includes(id)) {
      await user.updateOne({ $pull: { bookmarks: id } });
    }
  }
}
  • Related