#node.js #angular #mongodb #express #mongoose
#node.js #angular #mongodb #экспресс #мангуст
Вопрос:
Я пытаюсь удалить все комментарии, которые являются частью определенного сообщения в блоге, которое будет удалено с помощью mongoose. Я действительно не понимаю, почему мой код не работает.
const commentSchema = new mongoose.Schema({
message: { type: String, required: true },
likes: { type: Number, default: 0 },
parentBlog: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "Blog"
},
commenter: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User"
}
});
router.delete("/:title_url", checkAuth, (req, res) => {
const successMessage = "Successfully deleted blog post.";
const errorMessage = "Error in deleting blog post.";
Blog.findOne({ title_url: req.params.title_url })
.then(foundBlog => {
Comment.deleteMany({
parentBlog: foundBlog._id
});
foundBlog.remove();
console.log(foundBlog);
return res.status(200).json({ message: successMessage });
})
.catch(res.status(500).json({ message: errorMessage }));
});
Консоль.журнал регистрируется правильно, прямо перед тем, как я получу следующую ошибку:
(node:3108) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
Редактировать: Вот мое окончательное рабочее решение.
// delete Blog Post route
router.delete("/:title_url", checkAuth, (req, res) => {
const successMessage = "Successfully deleted blog post.";
const errorMessage = "Error in deleting blog post.";
// delete Post
Blog.findOneAndRemove({ title_url: req.params.title_url })
.populate("comments")
.then(async foundBlog => {
// delete Comment references from Commenters
await foundBlog.comments.forEach(async comment => {
await User.findByIdAndUpdate(comment.commenter._id, {
$pull: { comments: comment._id }
});
});
// delete Post reference from Post Author
await User.findByIdAndUpdate(foundBlog.author, {
$pull: { blogs: foundBlog._id }
});
// delete all child Comments
await Comment.deleteMany({
parentBlog: foundBlog._id
});
return res.status(200).json({ message: successMessage });
})
.catch(() => res.status(500).json({ message: errorMessage }));
});
Комментарии:
1. Я решил это. Я забыл выполнить функцию в блоке catch. В нем должно быть написано: catch(() => res.status(500).json({ сообщение: сообщение об ошибке }))
Ответ №1:
вы можете попробовать это —
router.delete("/:title_url", checkAuth, async (req, res) => {
const successMessage = "Successfully deleted blog post.";
const errorMessage = "Error in deleting blog post.";
try {
let foundBlog = await Blog.findOne({ title_url: req.params.title_url });
Comment.deleteMany({
parentBlog: foundBlog._id
});
foundBlog.remove();
console.log(foundBlog);
res.status(200).json({ message: successMessage });
} catch (error) {
res.status(500).json({ message: errorMessage })
}
});
На самом деле вы не обрабатываете отказ от обещания.
Я думаю, что таким образом код становится более понятным и читаемым
Надеюсь, что это поможет.
Комментарии:
1. привет, спасибо за ваш ответ. вы имели в виду, что я не обрабатываю это даже после моего комментария? чем именно ваш код отличается от моего? для меня это выглядит так, как будто это просто другой синтаксис. кроме того, разве ключевое слово «await» доступно только в асинхронной функции? почему это будет работать в вашем решении / какая часть кода делает эту функцию асинхронной?
2. Эй, это тот же код, но с небольшой разницей — в моем коде я обрабатываю перехват ошибок из обеих функций findOne и deleteMany (вы обрабатываете только ошибку функции find). Кроме того, я предпочитаю инициализировать все API при запуске сервера и использовать асинхронную функцию для каждого API
3. Ну, вы забыли ключевое слово «async», которое меня немного смутило. Но нет проблем, я понял это довольно быстро. Я редактирую свой пост и делюсь окончательным решением, которое я придумал. Дальнейшие улучшения (как я сокращаю код, лучшие практики, повышение производительности) по-прежнему приветствуются.