Curd Operation with React Js , Node Js and SQL Database

 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