The main objectives of this article are:
- Create A HTTP Delete Endpoint In NestJS App.
- Consume The Delete Endpoint in ReactJS App.
Create A HTTP Delete Endpoint In NestJS App:
Let's implement the HTTP Delete Endpoint in the NestJS Application.
Let's implement the delete operation logic in 'EmployeeService'.
NestJS_App/src/employee/employee.service.ts:
async delete(id: string) { await this.employeeModel.findByIdAndRemove(id); }
- Here 'findByIdAndRemove()' method deletes the document from the MongoDB collection.
Let's add the HTTP Delete endpoint in our 'EmployeeController'.
NestJS_App/src/employee/employee.controller.ts:
import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common'; import { EmployeeService } from './employee.service'; import { Employee } from './schema/employee-schema'; @Controller('employee') export class EmployeeController { constructor(private employeeService: EmployeeService) {} @Delete('/:id') async delete(@Param('id') id:string){ await this.employeeService.delete(id); } }
- Here '@Delete' decorator makes our method executes only for the HTTP delete request.
Create React Component 'DeleteConfirmation':
Let's create a new React component like 'DeleteConfirmation'. This is not going to be a page component, but it will be a shared component so that anywhere we can use this 'DeleteConfirmation' component so crate this component in 'components/shared folder'.
ReactJS_App/src/components/shared/DeleteConfirmation.js:
import Button from "react-bootstrap/Button"; import Modal from "react-bootstrap/Modal"; const DeleteConfirmation = (props) => { return ( <> <Modal show={props.showModal} onHide={() => { props.closeDeleteModalHandler(); }} > <Modal.Header closeButton> <Modal.Title>{props.title}</Modal.Title> </Modal.Header> <Modal.Body>{props.body}</Modal.Body> <Modal.Footer> <Button variant="secondary" onClick={() => { props.closeDeleteModalHandler(); }} > Close </Button> <Button variant="danger" onClick={() => { props.confirmDeleteHandler(); }} > Confirm Delete </Button> </Modal.Footer> </Modal> </> ); }; export default DeleteConfirmation;
- Here 'DeleteConfirmation' component contains react-bootstrap modal code.
- (Line: 8) The 'show' is the boolean property of the 'Modal' component. The parent component passes its value through 'props.showModal'(here showModal is our custom property name which must be passed by the parent component and its value should be boolean). So if 'show' property receives 'true' then opens the modal.
- (Line: 9-11) The 'onHide' get triggered by the 'X'(close button) on the right-top corner of the modal. Here 'onHide' register with an arrow function which internally calls a method of the parent component like 'props.closeDeleteModalHandler'.
- (Line: 14) Dynamic 'props.title' property for the modal title.
- (Line: 16) Dynamic 'props.body' property fo the modal body.
- (Line: 18-25)Close button click event to register with arrow function which internally calls a method of parents component like 'props.CloseDeleteModalHandler'.
- (Line: 26-33) Confirm delete button, click event register with arrow function which internally calls a method of parents component like 'props.confirmDeleteHandler'.
Invoke 'DeleteConfirmation' From 'AllEmployees' Component(Delete Operation):
Let's add the 'DeleteConfirmation' element into the 'AllEmployees' component so that whenever we click on the delete button 'DeleteConfirmation' modal will open.
ReactJS_App/src/pages/AllEmployees.js:
import { useEffect, useState } from "react"; import { Container, Table, Row, Col, Button } from "react-bootstrap"; import axios from "axios"; import { useNavigate } from "react-router-dom"; import DeleteConfirmation from "../components/shared/DeleteConfirmation"; const AllEmployees = () => { const [employees, setEmployees] = useState([]); const navigate = useNavigate(); const [showModal, setShowModal] = useState(false); const [itemIdToDelete, setItemIdToDelete] = useState(0); useEffect(() => { axios.get("http://localhost:4000/employee").then((response) => { setEmployees(response.data); }); },[]); const openDeleteModalHandler = (id) => { setItemIdToDelete(id); setShowModal(true); }; const closeDeleteModalHandler = () => { setItemIdToDelete(0); setShowModal(false); }; const confirmDeleteHandler = () => { axios .delete(`http://localhost:4000/employee/${itemIdToDelete}`) .then(() => { setEmployees((existingData) => { return existingData.filter((_) => _._id !== itemIdToDelete); }); setItemIdToDelete(0); setShowModal(false); }); }; return ( <> <DeleteConfirmation title="Delete Confimation!" body="Are sure to delete this item" showModal={showModal} closeDeleteModalHandler={closeDeleteModalHandler} confirmDeleteHandler={confirmDeleteHandler} ></DeleteConfirmation> <Container className="mt-2"> <Row> <Col className="col-md-4 offset-md-4"> <Button variant="primary" type="button" onClick={() => navigate("/add-employee")} > Add </Button> </Col> </Row> <Table striped bordered hover> <thead> <tr> <th>Name</th> <th>Job Role</th> <th>Experience</th> <th>Actions</th> </tr> </thead> <tbody> {employees.map((emp) => ( <tr key={emp._id}> <td>{emp.name}</td> <td>{emp.role}</td> <td>{emp.experience}</td> <td> <Button variant="primary" type="button" onClick={() => { navigate(`/edit-employee/${emp._id}`); }} > Edit </Button>{" "} | <Button variant="danger" type="button" onClick={() => { openDeleteModalHandler(emp._id); }} > Delete </Button> </td> </tr> ))} </tbody> </Table> </Container> </> ); }; export default AllEmployees;
- (Line: 10) The 'showModal' & 'setShowModal' are useState variables used to show and hide the Modal
- (Line: 11) The 'itemToDeleteId' & 'setItemToDeleteId' are useState variables used to maintain 'id' of the record need to be deleted.
- (Line: 19-22) The function 'openDeleteModalHandler' will invoke by the delete button. It contains logic like 'setShowModal' to true which opens the delete confirmation modal and 'setItemToDelteId' contains the record to be deleted
- (Line: 24-27) The function 'closeDeleteModalHandler' will invoke by the 'cancel' button on modal. It contains logic like 'setShowModal' to false which closes the modal and 'setItemToDeleteId' reset to value '0'.
- (Line: 29-39) The function 'confirmDeleteHandler' logic invokes the delete API call. After API success we are updating a few 'useState' variables. The 'setShowModal' is assigned to false to close the modal. The 'setEmployees' update to remove the deleted item from its array. The 'setItemToDeleteId' value reset to '0'
- (Line: 43-49) Rendered the 'DeleteConfirmation' component element with all required props
- (Line: 88-96) The 'Delete' button clicks the event registered with the arrow function it internally invoke the 'openDeleteModalHandler' by inputting the 'id' of the item to delete.
Support Me!
Buy Me A Coffee
PayPal Me
Video Session:
Wrapping Up:
Hopefully, I think this article delivered some useful information on NestJS(v9) | ReactJS(v18) CRUD sample. I love to have your feedback, suggestions, and better techniques in the comment section below.
Refer:
Part-1 | NestJS(v9) | ReactJS(v18) | MongoDB | CRUD Example
Part-2 | NestJS(v9) | ReactJS(v18) | MongoDB | CRUD Example
Part-3 | NestJS(v9) | ReactJS(v18) | MongoDB | CRUD Example
Part-2 | NestJS(v9) | ReactJS(v18) | MongoDB | CRUD Example
Part-3 | NestJS(v9) | ReactJS(v18) | MongoDB | CRUD Example
Part-4 | NestJS(v9) | ReactJS(v18) | MongoDB | CRUD Example
Part-5 | NestJS(v9) | ReactJS(v18) | MongoDB | CRUD
Part-5 | NestJS(v9) | ReactJS(v18) | MongoDB | CRUD
Great series, thank you!
ReplyDelete