0

First, apologies because I couldn't figure out a better title for this question. I am gonna try to explain my issue, let me know if you can't understand what is going on.

When deleting a movie, I also would like to delete the id of the movies from its genres arrays. Each Genre has a movie array with all the movie ids in that genre and each movie has a genre array with all the genre ids of that movie.

async delete(req, res, next) {
    try {
      const movie = await Movie.findOne({ _id: req.params.id });
      if (!movie) return res.status(400).send({ error: "Movie not found" });

    // Here I find all the genres. I get an array with all the genres objects
    // [{genre1}, {genre2}] inside the genre object there is an array with all the movie ids that belongs to that genre
      let _genres = await Genre.find({ _id: { $in: movie.genre } });

    // Now I am trying to return all the genre that are different from the movie._id I am deleting 
      _genres = await Promise.all(_genres.map(async (genre) => {
        genre.movies.filter(item => item !== movie._id);
        await genre.save();
        return genre;
      }));

      await movie.remove();
      return res.send({ deleted: true });
    } catch (e) {
      next(e);
    }
}

I am not getting any error, but it is not deleting the movie id from the genre. Thanks.

Windbox
  • 3,929
  • 3
  • 12
  • 20
  • 3
    `filter` creates a new array, it does not alter your `genre` object. – Bergi Dec 02 '19 at 02:36
  • Instead of searching for `_id: { $in: movie.genre }`, wouldn't make something like `movies: { $contains: id }` more sense? – Bergi Dec 02 '19 at 02:39
  • Thanks Bergi, I edited my question to reflect the changes in my code. – Windbox Dec 02 '19 at 02:55
  • 1
    @RandalAndrade If you found a solution, you might want to [post it as an answer](https://stackoverflow.com/help/self-answer) though. Btw, [don't use `forEach`](https://stackoverflow.com/q/37576685/1048572), the `Promise.all` + `map` was really fine! – Bergi Dec 02 '19 at 08:32

1 Answers1

0

Thanks to Bergi I was able to figure it out. Filter does not alter your object so I had to reassign it, I also had to convert the ids to strings to make sure they can be compared. Thanks Bergi.

Working code, if you think I can write it a better way let me know.

  async delete(req, res, next) {
    try {
      const movie = await Movie.findOne({ _id: req.params.id });
      if (!movie) return res.status(400).send({ error: "Movie not found" });


      movie.genre.forEach(async (id) => {
        const genre = await Genre.findById(id);
        if (genre) {
          genre.movies = genre.movies.filter(item => item.toString() !== movie._id.toString());
          await genre.save();
        }
      });

      await movie.remove();
      return res.send({ deleted: true });
    } catch (e) {
      next(e);
    }
  }
Windbox
  • 3,929
  • 3
  • 12
  • 20