Step 1 (Creating frontend and backend folders) :
---------
create a main folder - crud-app
create 2 sub folder - crud-app/client & crud-app/server
Go to client folder :
npx create-react-app .
Go to server folder :
npm init
npm install mysql express nodemon dotenv cors body-parser
Step 2 (creating first api) :
---------
Create dotenv file :
.env:
-------
PORT = 4000
Create server.js or index.js file insdie server folder(if not already present) -
server.js :
const express = require("express");
const app = express();
const cors = require("cors");
const dotenv = require("dotenv");
dotenv.config();
app.use(cors());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.get("/", (req, res) => {
res.send("running nicely");
});
app.listen(process.env.PORT, function (err) {
if (err) console.log(err);
console.log(`listening to port ${process.env.PORT}`);
});
Now go to browser and type : localhost:4000 and it should print "running nicely"
Step 3 - (creating a database):
Open xampp and run apache and mysql
Go to phpmyadmin -create database name , create tablename , create 2 columns and add one record -
database - crud_app
table_name : movie_reviews
column name 1 - movie_name
column name 2 - movie_comment
Step 4 - (setting up a database connection with backend) - :
Update .env :
-----------
PORT = 4000
HOST =localhost
USER = xxxxxx
PASSWORD = xxxxxx
TABLE = movie_reviews
DB_PORT = 3306
Create a new folder - crud-app/server/config/db.js
db.js :
----
const dotenv = require("dotenv");
const mysql = require("mysql");
dotenv.config();
const connection = mysql.createConnection({
host: process.env.HOST,
user: process.env.USER,
password: process.env.PASSWORD,
database: process.env.DATABASE,
});
connection.connect((error) => {
if (error) return console.log(error);
console.log("connection successfull");
});
module.exports = connection;
Step 5: Adding Read Operation in Backend
server.js:
-----------
const express = require("express");
const app = express();
const cors = require("cors");
const dotenv = require("dotenv");
const connection = require("./config/db");
dotenv.config();
app.use(cors());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.get("/", (req, res) => {
res.send("running nicely");
});
//read operation
app.get("/allData", (req, res) => {
const selectAllQuery = "SELECT * FROM movie_reviews";
connection.query(selectAllQuery, (err, rows) => {
if (err) {
console.log(err);
} else {
res.json({ rows });
// console.log(rows);
}
});
});
app.listen(process.env.PORT, function (err) {
if (err) console.log(err);
console.log(`listening to port ${process.env.PORT}`);
});
go to browser and type - localhost:4000/allData
it shoud show the data inside the movie_review table.
If it worked,the congrats, your read operation is working .
Step 6 - Creating logic in frontend for READ Operation
>Showing all the data from backend to frontend
frontend :
MovieReview.jsx :
---------------------
import React, { useEffect, useState } from "react";
import axios from "axios";
import "./MovieReview.css";
const MovieReview = () => {
const [movieName, setMovieName] = useState("");
const [movieComment, setMovieComment] = useState("");
const [allReviews, setAllReviews] = useState([]);
//----------------Read---------------
const getAllData = () => {
axios
.get("http://localhost:4000/allData")
.then((response) => setAllReviews(response.data.rows));
};
useEffect(() => {
getAllData();
}, [movieName, movieComment]);
return (
<>
<h5>Enter movie names </h5>
<form onSubmit={submitHandler}>
<div>
<input
type="text"
placeholder="movie name"
value={movieName}
onChange={(e) => setMovieName(e.target.value)}
/>
</div>
<div>
<input
type="text"
placeholder="movie comments"
value={movieComment}
onChange={(e) => setMovieComment(e.target.value)}
/>
</div>
<button type="submit" style={{ margin: 10, padding: 10 }}>
Submit
</button>
</form>
<hr />
<hr />
<div>
<table>
<tr>
<th>Id </th>
<th>Movie Name </th>
<th>Movie Comment </th>
</tr>
{allReviews.map((ele, i) => {
return (
<tr key={i}>
<td>{ele.id} </td>
<td>{ele.movie_name} </td>
<td>{ele.movie_comment} </td>
</tr>
);
})}
</table>
</div>
</>
);
};
export default MovieReview;
App.js :
import "./App.css";
import MovieReview from "./MovieReview";
function App() {
return (
<div className="App">
<h3>Crud Operation</h3>
<MovieReview />
</div>
);
}
export default App;
Step 7 - : Adding CREATE opeation in backned :
server.js :
const express = require("express");
const app = express();
const cors = require("cors");
const dotenv = require("dotenv");
const path = require("path");
dotenv.config();
app.use(cors());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.get("/", (req, res) => {
res.send("running nicely");
});
//--------------------------Create-------------------------------
app.post("/create", (req, res) => {
console.log("req from frontend", req.body);
let movie_name = req.body.name;
let movie_comment = req.body.comment;
try {
connection.query(
"INSERT INTO movie_reviews (movie_name, movie_comment) VALUES (?,?)",
[movie_name, movie_comment],
(err, result) => {
if (err) {
console.log(err);
} else {
res.json({ result });
}
}
);
} catch (error) {
res.send(error);
}
});
//--------------------------Read-------------------------------
app.get("/allData", (req, res) => {
const selectAllQuery = "SELECT * FROM movie_reviews";
connection.query(selectAllQuery, (err, rows) => {
if (err) {
console.log(err);
} else {
res.json({ rows });
// console.log(rows);
}
});
});
app.listen(process.env.PORT, function (err) {
if (err) console.log(err);
console.log(`listening to port ${process.env.PORT}`);
});
Creating logic in frontend for CREATE Operation
MovieReview.jsx
--------------------
import { useEffect, useState } from "react";
import axios from "axios";
import "./MovieReview.css";
const MovieReview = () => {
const [movieId, setMovieId] = useState();
const [movieName, setMovieName] = useState("");
const [movieComment, setMovieComment] = useState("");
const [allReviews, setAllReviews] = useState([]);
//----------------------------CREATE----------------------
//sending the user data to backend and storing in database
const submitHandler = (e) => {
e.preventDefault();
if (!movieName) {
alert("movie name can't be blank");
} else if (!movieComment) {
alert("comment name can't be blank");
} else {
console.log("submitteddddd...", movieName, movieComment);
axios.post("http://localhost:4000/create", {
name: movieName,
comment: movieComment,
});
setAllReviews([
...allReviews,
{ movie_name: movieName, movie_comment: movieComment },
]);
setMovieName("");
setMovieComment("");
}
};
//--------------------Read----------------
const getAllData = () => {
axios
.get("http://localhost:4000/allData")
.then((response) => setAllReviews(response.data.rows));
};
useEffect(() => {
getAllData();
}, [movieName, movieComment]);
return (
<>
<header className="headerSearch">
<div>
<input
type="text"
placeholder="Search..."
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
<button>FrontEnd Search🔍</button>
</div>
</header>
<main className="main">
<form onSubmit={submitHandler}>
<div>
<label>Movie name : </label>
<input
type="text"
placeholder="type movie name"
value={movieName}
onChange={(e) => setMovieName(e.target.value)}
/>
</div>
<div>
<label>Review : </label>
<input
type="text"
placeholder="type comments"
value={movieComment}
onChange={(e) => setMovieComment(e.target.value)}
/>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
</main>
<hr />
<hr />
<div className="table-div">
<table className="main-table">
<tbody>
<tr className="table-row">
<th>Id </th>
<th>Movie Name </th>
<th>Movie Comment </th>
<th colSpan="2">Actions</th>
</tr>
{allReviews
.map((ele, i) => {
return (
<tr key={i}>
<td>{ele.id} </td>
<td>{ele.movie_name} </td>
<td>{ele.movie_comment} </td>
<td>
<button
onClick={() =>
updateReview(
ele.id,
ele.movie_name,
ele.movie_comment
)
}
>
Edit
</button>
<button
className="deleteBtn"
onClick={() => deleteReview(ele.id)}
>
Delete
</button>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</>
);
};
export default MovieReview;
Step 8 : Adding the remaing - Delete ,update
server.js:
-----------
const express = require("express");
const app = express();
const cors = require("cors");
const dotenv = require("dotenv");
const path = require("path");
dotenv.config();
const connection = require("./config/db");
app.use(cors());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.get("/", (req, res) => {
res.send("running nicely");
});
//--------------------------Create-------------------------------
app.post("/create", (req, res) => {
console.log("req from frontend", req.body);
let movie_name = req.body.name;
let movie_comment = req.body.comment;
try {
connection.query(
"INSERT INTO movie_reviews (movie_name, movie_comment) VALUES (?,?)",
[movie_name, movie_comment],
(err, result) => {
if (err) {
console.log(err);
} else {
res.json({ result });
}
}
);
} catch (error) {
res.send(error);
}
});
//--------------------------Read-------------------------------
app.get("/allData", (req, res) => {
const selectAllQuery = "SELECT * FROM movie_reviews";
connection.query(selectAllQuery, (err, rows) => {
if (err) {
console.log(err);
} else {
res.json({ rows });
// console.log(rows);
}
});
});
//--------------------------Delete-------------------------------
app.delete(`/delete/:id`, (req, res) => {
const id = req.params.id;
const deleteQuery = "DELETE FROM movie_reviews where id = ?";
connection.query(deleteQuery, id, (err, result) => {
if (err) console.log(err);
});
});
//--------------------------Update-------------------------------
app.put("/update/:id", (req, res) => {
var id = req.params.id;
console.log("updating request", req.params.id);
console.log("updating request", req.body);
var movie_name = req.body.movie_name;
var movie_comment = req.body.movie_comment;
const updateQuery =
"UPDATE movie_reviews SET movie_comment = ? , movie_name = ? where id = ?";
connection.query(
updateQuery,
[movie_comment, movie_name, id],
(err, rows, fileds) => {
if (err) {
console.log(err);
} else {
console.log(rows, fileds);
}
}
);
});
app.listen(process.env.PORT, function (err) {
if (err) console.log(err);
console.log(`listening to port ${process.env.PORT}`);
});
Frontend -
> Adding Delete Login
> Adding Update Login
> Adding Search logic
MovieReviw.jsx:
------------------------
import { useEffect, useState } from "react";
import axios from "axios";
import "./MovieReview.css";
const MovieReview = () => {
const [movieId, setMovieId] = useState();
const [movieName, setMovieName] = useState("");
const [movieComment, setMovieComment] = useState("");
const [allReviews, setAllReviews] = useState([]);
const [search, setSearch] = useState("");
const [showUpdateBtn, setShowUpdateBtn] = useState(false);
//-----------------------CREATE-------------------
//sending the user data to backend and storing in database
const submitHandler = (e) => {
e.preventDefault();
if (!movieName) {
alert("movie name can't be blank");
} else if (!movieComment) {
alert("comment name can't be blank");
} else {
console.log("submitteddddd...", movieName, movieComment);
axios.post("http://localhost:4000/create", {
name: movieName,
comment: movieComment,
});
// .then((response) => setAllReviews(response.data.result));
setAllReviews([
...allReviews,
{ movie_name: movieName, movie_comment: movieComment },
]);
setMovieName("");
setMovieComment("");
}
};
//-----------------------READ------------------- //getting all data from database
const getAllData = () => {
axios
.get("http://localhost:4000/allData")
.then((response) => setAllReviews(response.data.rows));
};
//-----------------------update-------------------
const updateReview = (id, name, review) => {
setShowUpdateBtn(!showUpdateBtn);
console.log("picked for updating", name, review, id);
setMovieName(name);
setMovieComment(review);
setMovieId(id);
};
const updatingData = (e) => {
e.preventDefault();
console.log("updating name", movieName);
console.log("updating comment", movieComment);
console.log("movie id for updating", movieId);
axios.put(`http://localhost:4000/update/${movieId}`, {
movie_name: movieName,
movie_comment: movieComment,
});
setShowUpdateBtn(!showUpdateBtn);
setMovieName("");
setMovieComment("");
};
//----------------delete-----------
const deleteReview = (id) => {
console.log("deleteing id", id);
axios.delete(`http://localhost:4000/delete/${id}`);
getAllData();
};
return (
<div className="file-uploader">
<input type="file" onChange={handleFileInput} />
<button
onClick={(e) => fileInput.current && fileInput.current.click()}
className="btn btn-primary"
>
Upload Image
</button>
</div>
);
};
useEffect(() => {
getAllData();
}, [movieName, movieComment]);
console.log("alllReviews", allReviews);
return (
<>
<header className="headerSearch">
<div>
<input
type="text"
placeholder="Search..."
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
<button>FrontEnd Search🔍</button>
</div>
</header>
<main className="main">
<form onSubmit={submitHandler}>
<div>
<label>Movie name : </label>
<input
type="text"
placeholder="type movie name"
value={movieName}
onChange={(e) => setMovieName(e.target.value)}
/>
</div>
<div>
<label>Review : </label>
<input
type="text"
placeholder="type comments"
value={movieComment}
onChange={(e) => setMovieComment(e.target.value)}
/>
</div>
<div style={{ display: showUpdateBtn ? "none" : "block" }}>
<button type="submit">Submit</button>
</div>
</form>
<div style={{ display: showUpdateBtn ? "block" : "none" }}>
<button className="updateBtn" type="button" onClick={updatingData}>
Update
</button>
</div>
</main>
<hr />
<hr />
<div className="table-div">
<table className="main-table">
<tbody>
<tr className="table-row">
<th>Id </th>
<th>Movie Name </th>
<th>Movie Comment </th>
<th colSpan="2">Actions</th>
</tr>
{allReviews
.filter((val) => {
if (val === "") {
return val;
} else if (
val.movie_name.toLowerCase().includes(search.toLowerCase()) ||
val.movie_comment.toLowerCase().includes(search.toLowerCase())
) {
return val;
} else {
return null;
}
})
.map((ele, i) => {
return (
<tr key={i}>
<td>{ele.id} </td>
<td>{ele.movie_name} </td>
<td>{ele.movie_comment} </td>
<td>
<button
onClick={() =>
updateReview(
ele.id,
ele.movie_name,
ele.movie_comment
)
}
>
Edit
</button>
<button
className="deleteBtn"
onClick={() => deleteReview(ele.id)}
>
Delete
</button>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</>
);
};
export default MovieReview;
What you have learnt?
Complete crud operation using Node JS , MySql and ReactJs
Thank you for reading.
Himanshu Shekhar
0 Comments