The main objectives of this article are:
- Create A Get By Id HTTP Get Endpoint In NestJS.
- Create A HTTP Put Endpoint In NestJS.
- Consume NestJS HTTP Put Endpoint From The ReactJS
Create A Get By Id HTTP Get Endpoint In NestJS:
Let's create a get by id HTTP Get Endpoint. This endpoint is generally to fetch the record that needs to be edited.
In our 'EmployeeService' let's implement logic to fetch a document by the 'id' value.
NestJS_App/src/employee/employee.service.ts:
import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { Employee, EmployeeDocument } from './schema/employee-schema'; // existing code hidden for display purpose @Injectable() export class EmployeeService { constructor( @InjectModel(Employee.name) private employeeModel: Model<EmployeeDocument>, ) {} async getByid(id: string) { return await this.employeeModel.findById(id).exec(); } }
- (Line: 12-14) Fetching the document by 'id' value from the MongoDB collection using the 'find(id)' method.
NestJS_App/src/employee/employee.controller.ts:
import { Body, Controller, Get, Param, Post } from '@nestjs/common'; import { EmployeeService } from './employee.service'; import { Employee } from './schema/employee-schema'; //existing code hidden for display purpose @Controller('employee') export class EmployeeController { constructor(private employeeService: EmployeeService) {} @Get('/:id') async getById(@Param('id') id: string) { return await this.employeeService.getByid(id); } }
- (Line: 9) The '@Get("/:id")' contains dynamic route value like 'id' in the URL.
- (LIne: 10) Here '@Param('id')' decorator loads from the '@nestjs/common' library. The '@Param('id')' helps to read the dynamic part of the URL like our 'id' value.
Create HTTP Put Endpoint In NestJS Application:
Let's create a new HTTP Put Endpoint in the NestJS application to update the item.
In our 'EmployeeService' implement the logic to update the document.
NestJS_App/src/employee/employee.service.ts:
async update(id: string, employee: Employee) { return await this.employeeModel.findByIdAndUpdate(id, employee, { new: true, }); }
- The 'update()' method had input params like 'id'(document id value), 'employee'(document data to be updated).
- The 'findByIdAndUpdate()' async method updates the document data of the specified 'id'. Here additional option 'new:true' defines the need to return the updated document, if we don't specify explicitly by default it returns the document data before the update.
NestJS_App/src/employee/employee.controller.ts:
import { Body, Controller, 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) {} @Put('/:id') async update( @Param('id') id: string, @Body() employee: Employee, ) { return await this.employeeService.update(id, employee); } }
- (Line: 9) The '@Put' decorator makes our method can be consumed by an HTTP PUT request. Here we pass a dynamic route expression like ':/id' means the 'id' value will be a dynamic value.
- (Line: 11) Using '@Param' decorator read the 'id' value from the route.
- (Line: 12) Using '@Body' decorator read the form data that needs to be updated into our MongoDB document.
Create React Component 'EditEmployee':
Let's create a new React component like 'EditEmployee'.
ReactJS_App/src/pages/EditEmployee.js:
const EditEmployee = () => { return <></>; }; export default EditEmployee;Now configure the route for the 'EditEmployee' component in the 'App' component.
ReactJS_App/src/App.js:
import "./App.css"; import Layout from "./components/shared/Layout"; import { Route, Routes } from "react-router-dom"; import AllEmployees from "./pages/AllEmployees"; import AddEmployee from "./pages/AddEmployee"; import EditEmployee from "./pages/EditEmployee"; function App() { return ( <Layout> <Routes> <Route path="/" element={<AllEmployees />}></Route> <Route path="/add-employee" element={<AddEmployee />}></Route> <Route path="/edit-employee/:id" element={<EditEmployee />}></Route> </Routes> </Layout> ); } export default App;
- (Line: 14) Configured route for 'EditEmployee' component. Here we can observe dynamic route placeholders like ':id' which means our item 'id' value will be passed.
Consume NestJS HTTP Put Endpoint From ReactJS(Update Operation):
Let's consume the HTTP put endpoint from our ReactJS application.
ReactJS_App/src/pages/EditEmployee.js:
import axios from "axios"; import { useEffect, useRef } from "react"; import { Button, Col, Container, Row, Form } from "react-bootstrap"; import { useNavigate, useParams } from "react-router-dom"; const EditEmployee = () => { const name = useRef(""); const role = useRef(""); const experience = useRef(""); const { id } = useParams("id"); const navigate = useNavigate(); useEffect(() => { axios.get(`http://localhost:4000/employee/${id}`).then((response) => { let data = response.data; name.current.value = data.name; role.current.value = data.role; experience.current.value = data.experience; }); }); const updateEmployeeHandler = () => { var payload = { name: name.current.value, role: role.current.value, experience: experience.current.value, }; axios.put(`http://localhost:4000/employee/${id}`,payload) .then(() => { navigate("/"); }) }; return ( <> <Container className="mt-2"> <Row> <Col className="col-md-8 offset-md-2"> <legend>Update Emplyee Details</legend> <Form.Group className="mb-3" controlId="formName"> <Form.Label>Name</Form.Label> <Form.Control type="text" ref={name} /> </Form.Group> <Form.Group className="mb-3" controlId="formRole"> <Form.Label>Job Role</Form.Label> <Form.Control type="text" ref={role} /> </Form.Group> <Form.Group className="mb-3" controlId="formExperience"> <Form.Label>Experience</Form.Label> <Form.Control type="text" ref={experience} /> </Form.Group> <Button type="button" variant="primary" onClick={updateEmployeeHandler}> Edit </Button> </Col> </Row> </Container> </> ); }; export default EditEmployee;
- (Line: 7-9) Declared the 'useRef' variable which we use to read the form data.
- (Line: 10) The 'useParams()' loads from the 'react-router-dom' helps to read the dynamic data from the route.
- (Line: 11) Declared the 'navigate' variable of type 'useNavigate()'.
- (Line: 13-20) Here invoking the API by the 'id' value. It needs to be invoked only once on component so it's invoked inside of the 'useEffect'.
- (Line: 22-32) Created the 'updateEmployeeHandler' method which invokes our HTTP PUT API call.
Reactjs_App/src/pages/AllEmployees.js:
<Table striped bordered hover> <thead> <tr> <th>Actions</th> </tr> </thead> <tbody> {employees.map((emp) => ( <tr key={emp._id}> <td> <Button variant="primary" type="button" onClick={() => { navigate(`/edit-employee/${emp._id}`); }} > Edit </Button> </td> </tr> ))} </tbody> </Table>
- The 'Edit' button click event registered with the arrow function. Tha arrow function contains logic to navigate to 'EditEmployee' component.
(Step 3)
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-6 | NestJS(v9) | ReactJS(v18) | MongoDB | CRUD Example
Part-6 | NestJS(v9) | ReactJS(v18) | MongoDB | CRUD Example
Comments
Post a Comment