~~~~~~~~~~ (Contents) MERN ~~~~~~~~~~~
[MERN①] Express & MongoDB Setup
https://qiita.com/niyomong/private/3281af84486876f897f7
[MERN②]User API Routes & JWT Authentication
https://qiita.com/niyomong/private/c11616ff7b64925f9a2b
[MERN③] Profile API Routes
https://qiita.com/niyomong/private/8cff4e6fa0e81b92cb49
[MERN④] Post API
https://qiita.com/niyomong/private/3ce66f15375ad04b8989
[MERN⑤] Getting Started With React & The Frontend
https://qiita.com/niyomong/private/a5759e2fb89c9f222b6b
[MERN⑥] Redux Setup & Alerts
https://qiita.com/niyomong/private/074c27259924c7fd306b
[MERN⑦] React User Authentication
https://qiita.com/niyomong/private/37151784671eff3b92b6
[MERN⑧] Dashboard & Profile Management
https://qiita.com/niyomong/private/ab7e5da1b1983a226aca
[MERN⑨] Profile Display
https://qiita.com/niyomong/private/42426135e959c7844dcb
[MERN⑩] Posts & Comments
https://qiita.com/niyomong/private/19c78aea482b734c3cf5
[MERN11] デプロイ
https://qiita.com/niyomong/private/150f9000ce51548134ad
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Post Modelを作成
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PostSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'users',
},
text: {
type: String,
required: true,
},
name: {
type: String,
},
avatar: {
type: String,
},
likes: [
{
user: {
type: Schema.Types.ObjectId,
ref: 'users',
},
},
],
comments: [
{
user: {
type: Schema.Types.ObjectId,
ref: 'users',
},
text: {
type: String,
required: true,
},
name: {
type: String,
},
avatar: {
type: String,
},
date: {
type: Date,
default: Date.now,
},
},
],
date: {
type: Date,
default: Date.now,
},
});
module.exports = Post = mongoose.model('post', PostSchema);
2. Add Post Route
const express = require('express');
const router = express.Router();
const auth = require('../../middleware/auth');
const { body, validationResult } = require('express-validator');
const Post = require('../../models/Post');
const Profile = require('../../models/Profile');
const User = require('../../models/User');
// @route POST api/posts
// @desc Create a post
// @access Private
router.post(
'/',
[auth, [body('text', 'Text is required').not().isEmpty()]],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ erros: errors.array() });
}
try {
const user = await User.findById(req.user.id).select('-password');
const newPost = new Post({
text: req.body.text,
name: user.name,
avatar: user.avatar,
user: req.user.id,
});
const post = await newPost.save();
res.json(post);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
}
);
module.exports = router;
3. Get & Delete post Routes
// @route GET api/posts
// @desc Get all posts
// @access Public
router.get('/', async (req, res) => {
try {
const posts = await Post.find().sort({ date: -1 });
res.json(posts);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
// @route GET api/posts/:id
// @desc Get post by ID
// @access Public
router.get('/:id', async (req, res) => {
try {
const post = await Post.findById(req.params.id);
if (!post) {
return res.status(404).json({ msg: 'Post not found' });
}
res.json(post);
} catch (err) {
console.error(err.message);
if (err.kind === 'ObjectId') {
return res.status(404).json({ msg: 'Post not found' });
}
res.status(500).send('Server Error');
}
});
// @route DELETE api/posts/:id
// @desc Delete a post
// @access Private
router.delete('/:id', auth, async (req, res) => {
try {
const post = await Post.findById(req.params.id);
if (!post) {
return res.status(404).json({ msg: 'Post not found' });
}
// Check user
if (post.user.toString() !== req.user.id) {
return res.status(401).json({ msg: 'User not authorized' });
}
await post.remove();
res.json({ msg: 'Post removed' });
} catch (err) {
console.error(err.message);
if (err.kind === 'ObjectId') {
return res.status(404).json({ msg: 'Post not found' });
}
res.status(500).send('Server Error');
}
});
4. Post Like & Unlike Routes
...
// @route PUT api/posts/like/:id
// @desc Like a post
// @access Private
router.put('/like/:id', auth, async (req, res) => {
try {
const post = await Post.findById(req.params.id);
// Check if the post has already been liked
if (
post.likes.filter((like) => like.user.toString() === req.user.id).length >
0
) {
return res.status(400).json({ msg: 'Post already liked' });
}
post.likes.unshift({ user: req.user.id });
await post.save();
res.json(post.likes);
} catch (err) {
consoleerror(err.message);
res.status(500).send('Server Error');
}
});
// @route PUT api/posts/unlike/:id
// @desc Unlike a post
// @access Private
router.put('/unlike/:id', auth, async (req, res) => {
try {
const post = await Post.findById(req.params.id);
// Check if the post has already been liked
if (
post.likes.filter((like) => like.user.toString() === req.user.id)
.length === 0
) {
return res.status(400).json({ msg: 'Post has not yet been liked' });
}
// Get remove index
const removeIndex = post.likes
.map((like) => like.user.toString())
.indexOf(req.user.id);
post.likes.splice(removeIndex, 1);
await post.save();
res.json(post.likes);
} catch (err) {
consoleerror(err.message);
res.status(500).send('Server Error');
}
});
...
5. Add & Remove Comment Routes
// @route POST api/posts/comment/:id
// @desc Comment on a post
// @access Private
router.post(
'/comment/:id',
[auth, [body('text', 'Text is required').not().isEmpty()]],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ erros: errors.array() });
}
try {
const user = await User.findById(req.user.id).select('-password');
const post = await Post.findById(req.params.id);
const newComment = {
text: req.body.text,
name: user.name,
avatar: user.avatar,
user: req.user.id,
};
post.comments.unshift(newComment);
await post.save();
res.json(post.comments);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
}
);
// @route DELETE api/posts/comment/:id/:comment_id
// @desc Delete a comment
// @access Private
router.delete('/comment/:id/:comment_id', auth, async (req, res) => {
try {
const post = await Post.findById(req.params.id);
// Post out comment
const comment = post.comments.find(
(comment) => comment.id === req.params.comment_id
);
// Make sure comment exsits
if (!comment) {
return res.status(404).json({ msg: 'Comment does not exist' });
}
// Check user
if (comment.user.toString() !== req.user.id) {
return res.status(401).json({ msg: 'User not authorized' });
}
// Get remove index
const removeIndex = post.comments
.map((comment) => comment.user.toString())
.indexOf(req.user.id);
post.comments.splice(removeIndex, 1);
await post.save();
res.json(post.comments);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});