37
loading...
This website collects cookies to deliver better user experience
npm init
package.json
file. Now we need to add a few external dependencies to our app. So to do that run the following command:npm i body-parser cors express mongoose
MongoURI
as variable name."scripts": {
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"client-install": "cd client && npm install",
"dev": "concurrently -n server,client -c red,blue \"npm run server\" \"npm run client\"",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client",
"build": "npm run heroku-postbuild"
},
package.json
file should look like this:{
"name": "memories-app",
"version": "1.0.0",
"description": "A memories app made on MERN stack",
"main": "server.js",
"type": "module",
"scripts": {
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"client-install": "cd client && npm install",
"dev": "concurrently -n server,client -c red,blue \"npm run server\" \"npm run client\"",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client",
"build": "npm run heroku-postbuild"
},
"keywords": [],
"author": "Somsubhra Das",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"mongoose": "^5.10.13"
}
}
server.js
:import express from "express";
import bodyParser from "body-parser";
import mongoose from "mongoose";
import cors from "cors";
import { config } from "dotenv";
import postRoutes from "./routes/post.js";
config();
const app = express();
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));
app.use(cors());
const CONNECTION_URL = process.env.MongoURI;
mongoose
.connect(CONNECTION_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
})
.then(() => console.log("Successfully connected to MongoDB"))
.catch((err) => console.log(`Error connecting to MongoDB ${err.message}`));
// app.get("/", (req, res) => res.send("Hello"));
app.use("/posts", postRoutes);
// Serve static assets if it's production environment
if (process.env.NODE_ENV === "production") {
// Set static folder
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
}
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server is running on port ${PORT}`));
postMessage.js
file. Copy the following to the file:import mongoose from "mongoose";
const postSchema = mongoose.Schema({
title: String,
message: String,
creator: String,
tags: [String],
selectedFile: String,
likeCount: {
type: Number,
default: 0,
},
createdAt: {
type: Date,
default: new Date(),
},
});
const PostMessage = mongoose.model("PostMessage", postSchema);
export default PostMessage;
post.js
and enter the following:import express from "express";
import {
getPosts,
createPost,
updatePost,
deletePost,
likePost,
} from "../controllers/posts.js";
const router = express.Router();
router.get("/", getPosts);
router.post("/", createPost);
router.patch("/:id", updatePost);
router.delete("/:id", deletePost);
router.patch("/:id/likePost", likePost);
export default router;
posts.js
:import PostMessage from "../models/postMessage.js";
import mongoose from "mongoose";
export const getPosts = async (req, res) => {
try {
const postMessages = await PostMessage.find();
// console.log(postMessages);
return res.json(postMessages);
} catch (error) {
res.status(404).json({ message: error.message });
}
};
export const createPost = async (req, res) => {
const post = req.body;
// console.log(req.body);
const newPost = new PostMessage(post);
try {
await newPost.save();
res.status(201).json(newPost);
} catch (error) {
res.status(409).json({ message: error.message });
}
};
export const updatePost = async (req, res) => {
const { id: _id } = req.params;
const post = req.body;
if (!mongoose.Types.ObjectId.isValid(_id)) {
return res.status(404).send("No post with that id");
}
const updatedPost = await PostMessage.findByIdAndUpdate(_id, post, {
new: true,
});
return res.json(updatedPost);
};
export const deletePost = async (req, res) => {
const { id: _id } = req.params;
if (!mongoose.Types.ObjectId.isValid(_id)) {
return res.status(404).send("No post with that id");
}
await PostMessage.findByIdAndRemove(_id);
return res.json({ message: "Post deleted successfully" });
};
export const likePost = async (req, res) => {
const { id } = req.params;
if (!mongoose.Types.ObjectId.isValid(id)) {
return res.status(404).send("No post with that id");
}
const updatedPost = await PostMessage.findByIdAndUpdate(
id,
{
$inc: { likeCount: 1 },
},
{ new: true }
);
return res.json(updatedPost);
};
npx create-react-app client
client
with all the frontend code. Change directory to client and run:npm i @material-ui/core @material-ui/icons axios moment react-redux redux redux-thunk
posts.js
and enter the following code:import {
CREATE,
UPDATE,
DELETE,
LIKE,
FETCH_ALL,
} from "../constants/actionTypes";
import * as api from "../api";
// Action Creators
export const getPosts = () => async (dispatch) => {
try {
const { data } = await api.fetchPosts();
// const action = { type: "FETCH_ALL", payload: [] };
dispatch({ type: FETCH_ALL, payload: data });
} catch (error) {
console.log(error.message);
}
};
export const createPost = (post) => async (dispatch) => {
try {
const { data } = await api.createPost(post);
dispatch({ type: CREATE, payload: data });
} catch (error) {
console.log(error);
}
};
export const updatePost = (id, post) => async (dispatch) => {
try {
const { data } = await api.updatePost(id, post);
dispatch({ type: UPDATE, payload: data });
} catch (error) {
console.log(error.message);
}
};
export const deletePost = (id) => async (dispatch) => {
try {
await api.deletePost(id);
dispatch({ type: DELETE, payload: id });
} catch (error) {
console.log(error);
}
};
export const likePost = (id) => async (dispatch) => {
try {
const { data } = await api.likePost(id);
dispatch({ type: LIKE, payload: data });
} catch (error) {
console.log(error.message);
}
};
index.js
:import axios from "axios";
const url = "/posts";
export const fetchPosts = () => axios.get(url);
export const createPost = (newPost) => axios.post(url, newPost);
export const updatePost = (id, updatedPost) =>
axios.patch(`${url}/${id}`, updatedPost);
export const deletePost = (id) => axios.delete(`${url}/${id}`);
export const likePost = (id) => axios.patch(`${url}/${id}/likePost`);
index.js
& posts.js
:import { combineReducers } from "redux";
import posts from "./posts";
export default combineReducers({ posts });
import {
CREATE,
FETCH_ALL,
DELETE,
LIKE,
UPDATE,
} from "../constants/actionTypes";
export default (posts = [], action) => {
switch (action.type) {
case FETCH_ALL:
return action.payload;
case CREATE:
return [...posts, action.payload];
case UPDATE:
case LIKE:
return posts.map((post) =>
post._id === action.payload._id ? action.payload : post
);
case DELETE:
return posts.filter((post) => post._id !== action.payload);
default:
return posts;
}
};
actionTypes.js
:export const CREATE = "CREATE";
export const UPDATE = "UPDATE";
export const DELETE = "DELETE";
export const FETCH_ALL = "FETCH_ALL";
export const LIKE = "LIKE";
src/index.js
and edit the contents to make the file resemble the following:import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { Provider } from "react-redux";
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import reducers from "./reducers";
import "./index.css";
const store = createStore(reducers, compose(applyMiddleware(thunk)));
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
app.js
, index.css
, style.js
to your project directory as well.npm run dev