I'm creating a post hook to create a slug after the a Post has been save. When I try and use Postman the check my result, the process go into limbo (no data was returned).I am using [email protected].
Code for the post hook:
PostsSchema.post("save", async function (doc, next) {
try {
doc.postSlug = slugify(doc.postTitle, { lower: true });
await doc.save();
return next();
} catch (err) {
console.log("inside catch method");
return next(createError(500, err.message));
}
});
Code for the route I use:
module.exports.createPost = async (req, res, next) => {
const { postTitle, postContent, postAuthor } = req.body;
try {
// check if author exist
const authorExist = await AccountsModel.findById(postAuthor);
if (!authorExist) {
return next(createError(404, `Author ID: ${postAuthor} Not Found`));
}
// create post
console.log("route 1")
const postNew = new PostsModel({
postTitle: postTitle,
postContent: postContent,
postAuthor: postAuthor,
});
await postNew.save();
// populate data for return
let postCreated = await postNew.populate("postAuthor");
return res.status(200).json({
code: 1,
success: true,
message: "New Post Created",
data: postCreated,
});
} catch (error) {
return next(createError(500, error.message));
}
};
I did fix this by removing the await in front of the doc.save():
PostsSchema.post("save", async function (doc, next) {
try {
doc.postSlug = slugify(doc.postTitle, { lower: true });
doc.save();
return next();
} catch (err) {
console.log("inside catch method");
return next(createError(500, err.message));
}
});
Also, using .then() also return the result:
PostsSchema.post("save", async function (doc, next) {
doc.postSlug = slugify(doc.postTitle, { lower: true });
console.log(1);
doc
.save()
.then(() => {
console.log(2);
return next();
})
.catch((error) => {
return next(createError(500, err.message));
});
});
But found some other post what have await and the answers indicate that it is not the problem:
- How to properly make a Mongoose post hook async
- Mongoose post save hook , update the document
- Async function in mongoose pre save hook not working. pre hook seems to work just fine with the await.
- https://stackoverflow.com/a/76738359/14723731. This one is the same as mine where they don't use an await method
So, I am wondering is it the await that break the process or something else?
I found the problem, when I
console.log(1)within your post hook, it creates an infinite loop. Based on a comment under 1 of the post Mongoose post save hook , update the document, post hook is executed after a.save()is performed; and inside your post hook, you perform another.save()which call your post hook again, creating an infinite loop.Your
await doc.save()doesn't work because it's waiting for the infinite loop to complete. That is why there is no response in postman, it never reached thereturn next()section.Your
doc.save()"works" because.save()is asynchronous; before it could complete its process, it has already reached to thereturn next()section that is why there is a value returned to postman while the code stays in an infinite loop.Your
doc.save().then()"works" because.then()resolves your.save()and get to thereturn next()but it invokes the post hook again, creating an infinite loop.I recommend either change the keyword pass in the hook or change to pre hook:
This pre hook runs before the actual
save()operation, so you don't call this hook again after saving it.