// route
router.post("/comment/:postId", requireSignin, createComment);
// controller
export const createComment = async (req, res) => {
// console.log(req.body);
try {
const { postId } = req.params;
const { comment } = req.body;
let created = await new Comment({
content: comment,
postId,
postedBy: req.user._id,
}).save();
created = await created.populate("postedBy", "_id name");
res.json(created);
} catch (err) {
console.log(err);
}
};
// components/comments/CommentForm.js
import { useContext } from "react";
import { Input, Button } from "antd";
import { AuthContext } from "../../context/auth";
import Link from "next/link";
const { TextArea } = Input;
const CommentForm = ({ handleSubmit, comment, setComment, loading }) => {
// context
const [auth, setAuth] = useContext(AuthContext);
console.log(auth);
return (
<>
<TextArea
value={comment}
onChange={(e) => setComment(e.target.value)}
disabled={auth.user === null && auth.token === ""}
rows={4}
placeholder="Leave a comment"
maxLength={200}
/>
<Button
onClick={handleSubmit}
disabled={(auth.user === null && auth.token === "") || comment === ""}
type="primary"
loading={loading}
style={{ marginTop: 4 }}
>
Post
</Button>
</>
);
};
export default CommentForm;
Now import and use in post/[slug].js
{auth.user === null && auth.token === "" ? (
<Link href="/signin">
<a>Login to comment</a>
</Link>
) : (
<h3>{comments.length} Comments</h3>
)}
<CommentForm
handleSubmit={handleSubmit}
comment={comment}
setComment={setComment}
loading={loading}
/>
// state and functions
// state
const [comment, setComment] = useState("");
const [comments, setComments] = useState(postComments);
const [loading, setLoading] = useState(false);
const handleSubmit = async () => {
try {
setLoading(true);
const { data } = await axios.post(`/comment/${post._id}`, { comment });
console.log("comment posted", data);
setComment("");
setComments([data, ...comments]);
toast.success("Comment posted successfully");
setLoading(false);
} catch (err) {
console.log(err);
toast.error("Comment post failed. Try again.");
setLoading(false);
}
};
// render list of comments for posts
// modify `singlePost` controller function to send post comments too
export const singlePost = async (req, res) => {
try {
const { slug } = req.params;
const post = await Post.findOne({ slug })
.populate("postedBy", "_id name")
.populate("categories", "_id name slug")
.populate("featuredImage", "_id url");
// comments
const comments = await Comment.find({ postId: post._id })
.populate("postedBy", "_id name")
.sort({ createdAt: -1 });
return res.json({ post, comments });
} catch (err) {
console.log(err);
res.sendStatus(400);
}
};
Since our controller for single post is modified (returns posts and comments), update your code in post create and update components:
const { title, content, featuredImage } = data.post;