How To Implement CRUD In Next.js

Here, we learn how to create APIs and crud operation in the next.js.

First, open the next.js application in the code editor.

Then install mongoose and mongodb for database connection and react-bootstrap and bootstrap for styling component.

BackEnd Part:-

For DB connection create the config folder and inside that create the db.js file, then write the below code in that.

import mongoose from "mongoose";

const connection = {};

async function dbConnect() {
    if (connection.isConnected) {
        return;
    }
    const db = await mongoose.connect(process.env.databaseURL, {
        useNewUrlParser: true,
        useUnifiedTopology: true,
    });
    connection.isConnected = db.connections[0].readyState;
}

export default dbConnect;

Then create a model in that database, for that create the model folder, and inside that create the student.js file, then write the below code in that.

"use strict";
const mongoose = require("mongoose");

const studentSchema = new mongoose.Schema(
    {
        firstName: { type: String, default: "", trim: true, required: true, },
        lastName: { type: String, default: "", trim: true, required: true, },
        age: { type: Number, trim: true, required: true, },
        email: { type: String, default: "", trim: true, required: true, },
        phoneNumber: { type: Number, trim: true, required: true, },
        city: { type: String,  default: "", trim: true, required: true, },
        password: { type: String, default: "", trim: true, required: true, }
    },
    { timestamps: true, }
);

module.exports = mongoose.models.students || mongoose.model("students", studentSchema);

Now, to create APIs we need to create a student folder inside pages>api.

Then create different js files for get-all, add, get-by-id, delete and update data.

And our files look like this,

get-all.js:-

import dbConnect from "../../../config/db";
import student from "../../../models/student";
const STUDENT = student;

dbConnect();

export default async (req, res) => {
    const { method } = req;
    switch (method) {
        case "GET":
            try {
                const studentData = await STUDENT.find({});
                if (!studentData) {
                    res.status(400).json({
                        isSuccess: false,
                        message: "Failed!",
                    });
                } else {
                    res.status(200).json({
                        isSuccess: true,
                        data: studentData,
                    });
                }
            } catch (error) {
                res.status(400).json({
                    isSuccess: false,
                    message: error,
                });
            }
            break;
        default:
            res.status(400).json({
                isSuccess: false,
                message: "Error",
            });
            break;
    }
};

add.js:-

...
    switch (method) {
        case "POST":
            try {
                const studentData = await STUDENT.create(req.body);

                if (!studentData) {
                    res.status(400).json({
                        isSuccess: true,
                        message: "Failed",
                    });
                } else {
                    res.status(201).json({
                        isSuccess: true,
                        message: "Success",
                    });
                }
            } catch (error) {
                res.status(400).json({
                    isSuccess: false,
                    message: error,
                });
            }
            break;
...

get-by-id.js:-

...
    switch (method) {
        case "GET":
            try {
                const studentData = await STUDENT.findById({ _id: req.query.id });
                if (!studentData) {
                    res.status(400).json({
                        isSuccess: false,
                        message: "Data not found!",
                    });
                } else {
                    res.status(200).json({
                        isSuccess: true,
                        data: studentData,
                    });
                }
            } catch (error) {
                res.status(400).json({
                    isSuccess: false,
                    message: error,
                });
            }
            break;
...

delete.js:-

...
    switch (method) {
        case "DELETE":
            try {
                const studentData = await STUDENT.deleteOne({ _id: req.query.id });

                if (!studentData) {
                    res.status(400).json({
                        isSuccess: false,
                        message: "Data not found!",
                    });
                } else {
                    res.status(202).json({
                        isSuccess: true,
                        message: "Success",
                    });
                }
            } catch (error) {
                res.status(400).json({
                    isSuccess: false,
                    message: error,
                });
            }
            break;
...

update.js:-

...
    switch (method) {
        case "POST":
            try {
                const studentData = await STUDENT.findByIdAndUpdate( { _id: req.body._id }, req.body, { new: true, } );
                if (!studentData) {
                    res.status(400).json({
                        isSuccess: false,
                        message: "Data not found!",
                    });
                } else {
                    res.status(202).json({
                        isSuccess: true,
                        message: "Success",
                    });
                }
            } catch (error) {
                res.status(400).json({
                    isSuccess: false,
                    message: error,
                });
            }
            break;
...

Now, use these APIs to create a studentApi.js file inside axios>sevices and create URLs.

import axios from "axios";

const baseUrl = process.env.API_URL

const getAllData = () => {
    return axios.get(baseUrl + "/get-all");
};

const addData = (data) => {
    return axios.post(baseUrl + "/add", data);
};

const deleteData = (id) => {
    return axios.delete(baseUrl + `/delete?id=${id}`);
};

const getByIdData = (id) => {
    return axios.get(baseUrl + `/get-by-id?id=${id}`);
};

const updateData = (data) => {
    return axios.post(baseUrl + "/update", data);
};

export { getAllData, addData, deleteData, getByIdData, updateData }

FrontEnd Part:-

First create Data.jsx file inside the pages folder, to show the table.

Here call get-all data API and set this in useState and show using the map function.

import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'
import { Button, Container, Row, Table } from 'react-bootstrap'
import { getAllData } from '../axios/services/studentApi'

const Data = () => {
    const router = useRouter()
    const [allData, setAllData] = useState([])
    const getData = () => {
        getAllData()
            .then(res => setAllData(res.data.data))
            .catch(error => console.log('error', error))
    }
    useEffect(() => {
        getData()
    }, [])
    return (
        <div>
            <Container>
                <Row>
                    <Table bordered hover>
                        <thead>
                            <tr>
                                <th>Count</th>
                                <th>Id</th>
                                <th>First Name</th>
                                <th>Last Name</th>
                                <th>Age</th>
                                <th>Email</th>
                                <th>Phone Number</th>
                                <th>City</th>
                                <th>Action</th>
                            </tr>
                        </thead>
                        <tbody>
                            {allData.map((e, i) => {
                                return (
                                    <tr key={i}>
                                        <td>{e._id}</td>
                                        <td>{e.firstName}</td>
                                        <td>{e.lastName}</td>
                                        <td>{e.age}</td>
                                        <td>{e.email}</td>
                                        <td>{e.phoneNumber}</td>
                                        <td>{e.city}</td>
                                        <td>
                                            <Button variant="outline-info" onClick={() => editApiData(e._id)} className='mx-2'>Edit</Button>
                                            <Button variant="outline-danger" onClick={() => deleteApiData(e._id)}>Delete</Button>
                                        </td>
                                    </tr>
                                )
                            })}
                        </tbody>
                    </Table>
                </Row>
            </Container>
        </div>
    )
}

export default Data

Now, create add button on this page and create a form.js file inside the pages folder and also create a form in the form.js file.

//In Data.jsx file
<Button variant="outline-success" onClick={() => router.push('/form')}><strong>+</strong> Add Data</Button>

//In form.js file
import { useRouter } from 'next/router'
import { useEffect, useState } from "react"
import { Button, Col, Container, Form, Row } from "react-bootstrap"
import { addData } from "../axios/services/studentApi"


const form = () => {
    const router = useRouter()
    const { query: { id } } = router
    const [dataObject, setDataObject] = useState({ firstName: '', lastName: '', email: '', password: '', age: '', phoneNumber: '', city: '' })
    const inputChange = (e) => {
        setDataObject({ ...dataObject, [e.target.name]: e.target.value })
    }
    const dataSubmit = (e) => {
        e.preventDefault()
            addData(dataObject)
                .then(res => {
                    if (res.data.isSuccess) {
                        router.push('/')
                    }
                    else {
                        alert(res.data.message)
                    }
                })
                .catch(error => console.log('error', error))
    }
    return (
        <>
            <div className='backgroundImage' style={{ height: '100vh' }}>
                <Container className='d-flex justify-content-center pt-4'>
                    <Form onSubmit={dataSubmit} className='w-75 p-3 formboader'>
                        <Row className="mb-3">
                            <Form.Group as={Col} controlId="firstName">
                                <Form.Label>First Name</Form.Label>
                                <Form.Control type="text" name='firstName' value={dataObject.firstName} onChange={inputChange} placeholder="Enter first name" />
                            </Form.Group>
                            <Form.Group as={Col} controlId="lastName">
                                <Form.Label>Last Name</Form.Label>
                                <Form.Control type="text" name='lastName' value={dataObject.lastName} onChange={inputChange} placeholder="Enter last name" />
                            </Form.Group>
                        </Row>
                        <Row className="mb-3">
                            <Form.Group as={Col} controlId="email">
                                <Form.Label>Email</Form.Label>
                                <Form.Control type="email" name='email' value={dataObject.email} onChange={inputChange} placeholder="Enter email" />
                            </Form.Group>
                            <Form.Group as={Col} controlId="password">
                                <Form.Label>Password</Form.Label>
                                <Form.Control type="password" name='password' value={dataObject.password} onChange={inputChange} placeholder="Enter password" />
                            </Form.Group>
                        </Row>
                        <Row className="mb-3">
                            <Form.Group as={Col} controlId="age">
                                <Form.Label>Age</Form.Label>
                                <Form.Control type="number" name='age' value={dataObject.age} onChange={inputChange} placeholder="Enter age" />
                            </Form.Group>
                            <Form.Group as={Col} controlId="phoneNumber">
                                <Form.Label>Phone Number</Form.Label>
                                <Form.Control type="number" name='phoneNumber' value={dataObject.phoneNumber} onChange={inputChange} placeholder="Enter phone number" />
                            </Form.Group>
                            <Form.Group as={Col} controlId="city">
                                <Form.Label>City</Form.Label>
                                <Form.Control type="text" name='city' value={dataObject.city} onChange={inputChange} placeholder="Enter city" />
                            </Form.Group>
                        </Row>
                        <Button className="btncss" type="submit"> Submit </Button>
                    </Form>
                </Container>
            </div>
        </>
    )
}

export default form

To delete data we create a function in Data.jsx file on click event.

 const deleteApiData = (id) => {
        const isconfirm = window.confirm(`Are you sure you want to delete ${id} data?`);
        if (isconfirm) {
            deleteData(id)
                .then(res => {
                    console.log(res.data)
                    getData()
                })
                .catch(error => console.log('error', error))
        }
    }

//html
<Button variant="outline-danger" onClick={() => deleteApiData(e._id)}>Delete</Button>

To edit data,

//In Data.jsx file
const editApiData = (id) => {
        console.log(id)
        router.push({
            pathname: "/form",
            query: { id: id },
        })
}
<Button variant="outline-info" onClick={() => editApiData(e._id)} className='mx-2'>Edit</Button>

//In form.js file
...
   let editID = 0
    useEffect(() => {
        console.log('id', id)
        // axios.get(baseURl + `/get-by-id?id=${id}`)
        getByIdData(id)
            .then(res => {
                console.log(res.data)
                setDataObject({ ...res.data.data, id });
                editID = id
            })
            .catch(error => console.log('error', error))
    }, [id])
    const dataSubmit = (e) => {
        e.preventDefault()
        if (editID) {
            updateData(dataObject)
                .then(res => {
                    if (res.data.isSuccess) {
                        router.push('/')
                    }
                    else {
                        alert(res.data.message)
                    }
                    editID = 0
                })
                .catch(error => console.log('error', error))
        }
        else {
            // add data function or api call
        }
    }
......

Output:-

Submit a Comment

Your email address will not be published.

Subscribe

Select Categories