The main objectives of this article are:
(Step 2)
In the next article, we will implement the delete operation.
- Create A Get By Id HTTP Get Endpoint In NestJS.
- Create A HTTP Put Endpoint In NestJS.
- Create Update Form In Angular App.
Create A Get By Id HTTP Get Endpoint In NestJS:
Let's create a get by id HTTP Get Endpoint. This endpoint is general to fetch the record that needs to be edited.
In our 'SuperHeroesService' let's implement logic to fetch a document by the 'id' value.
NestJS_App/src/super-heroes/super-heroes.service.ts:
NestJS_App/src/super-heroes/super-heroes.service.ts:
import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { SuperHeroes, SuperHeroesDocument } from './schema/super-heroes.schema'; // existing code hidden for display purpose @Injectable() export class SuperHeroesService { constructor( @InjectModel(SuperHeroes.name) private superHeroModel: Model<SuperHeroesDocument>, ) {} async getByid(id: string) { return await this.superHeroModel.findById(id).exec(); } }
- (Line: 13-15) Fetching the document by 'id' value from the MongoDB collection using the 'find(id)' method.
Now let's create the get by id HTTP get endpoint in our 'SuperHeroesController'.
NestJS_App/src/super-heroes/super-heroes.controller.ts:
import { Body, Controller, Get, Param, Post } from '@nestjs/common'; import { SuperHeroes } from './schema/super-heroes.schema'; import { SuperHeroesService } from './super-heroes.service'; @Controller('super-heroes') export class SuperHeroesController { constructor(private superHeroService:SuperHeroesService){} @Get("/:id") async getById(@Param('id') id:string){ return await this.superHeroService.getByid(id); } }
- (Line: 10) The '@Get(''/:id")' contains dynamic route value like 'id' in the URL.
- (Line: 11) 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 A HTTP Put Endpoint In NestJS:
In our 'SuperHeroesService' implement logic to update the document.
NestJS_App/src/super-heroes/super-heroes.service.ts:
import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { SuperHeroes, SuperHeroesDocument } from './schema/super-heroes.schema'; // existing code hidden for display purpose @Injectable() export class SuperHeroesService { constructor( @InjectModel(SuperHeroes.name) private superHeroModel: Model<SuperHeroesDocument>, ) {} async update(id: string, superHeroes: SuperHeroes) { return await this.superHeroModel.findByIdAndUpdate(id, superHeroes, { new: true, }); } }
- (Line: 13) The 'update()' method had input params like 'id'(document id value), 'superHeroes'(document data to be updated).
- The 'findByIdAndUpdate' async method updates the document data of specified 'id'. Here additional options 'new:true' defines the need to return the updated document, if we don't specify it explicitly by default it returns the document data before the update.
NestJS_App/src/super-heroes/super-heroes.controller.ts:
import { Body, Controller, Get, Param, Post, Put } from '@nestjs/common'; import { SuperHeroes } from './schema/super-heroes.schema'; import { SuperHeroesService } from './super-heroes.service'; @Controller('super-heroes') export class SuperHeroesController { constructor(private superHeroService: SuperHeroesService) {} @Put('/:id') async updateSuperHero( @Param('id') id: string, @Body() superHeroes: SuperHeroes, ) { return await this.superHeroService.update(id, superHeroes); } }
- (Line: 9) The '@Put' decorator makes our method can be consumed by an HTTP PUT request. Here we pass dynmic route expression like '/:id' means the 'id' value will be a dynamic value
- (Line: 11) Using the '@Param' decorator read the 'id' value from the route.
- (Line: 12) Using the '@Body' param read the form data that needs to be updated into our MongoDB document.
Create A New Angular Component 'EditSuperHeroesComponent':
Let's create a new angular component like 'EditSuperHeroesComponent'.
ng generate component super-heroes/edit-super-heroes --skip-tests
Configure the route of 'EditSuperHeroesComponent' in 'AppRoutingModule'.
Angular_App/src/app/app-routing.module.ts:
import { EditSuperHeroesComponent } from './super-heroes/edit-super-heroes/edit-super-heroes.component'; //existing code hidden for display purpose const routes: Routes = [ { path: 'edit-super-hero/:id', component: EditSuperHeroesComponent, } ];
Implement API Invoke Logic In Angular App 'SuperHeroesService':
Let's implement API invoke logic in our 'SuperHereosService'.
Angular_App/src/app/super-heroes/super-heroes.service.ts:
getById(id: string) { return this.http.get<SuperHeroes>( `http://localhost:3000/super-heroes/${id}` ); } update(id: string, superHero: CreateOrUpdateSuperHero) { return this.http.put(`http://localhost:3000/super-heroes/${id}`, superHero); }
- (Line: 1-5) The HTTP Get API to fetch item need to be updated. Here to frame dynamic value to API call we have to use "`${}`".
- (Line: 7-9) The HTTP PUT API to update the document data.
Update Form:
Let's implement the update form logic in 'EditSuperHeroesComponent'.
Angular_App/src/super-heroes/edit-super-heroes/edit-super-heroes.component.ts:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { CreateOrUpdateSuperHero } from '../create-or-update-super-hero'; import { SuperHeroesService } from '../super-heroes.service'; @Component({ selector: 'app-edit-super-heroes', templateUrl: './edit-super-heroes.component.html', styleUrls: ['./edit-super-heroes.component.css'], }) export class EditSuperHeroesComponent implements OnInit { constructor( private route: ActivatedRoute, private router: Router, private superHeroService: SuperHeroesService ) {} itemId: string = ''; superHeroes: CreateOrUpdateSuperHero = { name: '', franchise: '', imageUrl: '', powers: '', }; ngOnInit(): void { this.route.paramMap.subscribe((param) => { this.itemId = param.get('id') ?? ''; this.getById(); }); } getById() { this.superHeroService.getById(this.itemId).subscribe((data) => { this.superHeroes.franchise = data.franchise; this.superHeroes.imageUrl = data.imageUrl; this.superHeroes.powers = data.powers; this.superHeroes.name = data.name; }); } update() { this.superHeroService .update(this.itemId, this.superHeroes) .subscribe(() => { this.router.navigate(['/']); }); } }
- (Line: 13&14) Injected the 'ActivatedRoute', and 'Router' services which load from the '@angular/router'.
- (Line: 15) Injected the 'SuperHeroesService'.
- (Line: 18) The 'itemId' variable stores the 'id' value of the document we want to update.
- (Line: 19-24) The 'superHeroes' variable of type 'CreateOrUpdateSuperHeroes' used for update form modal binding.
- (Line: 27-29) Using the 'ActivatedRoute' service read the 'id' value from the angular router URL.
- (Line: 32-39) Invoking the get by id API call and response assigned to the 'superHeroes' variable object so that the edit form gets populated with the data.
- (Line: 41-47) Invokes the update API call and on success navigates back to the home page.
Angular_App/src/app/super-heroes/edit-super-heroes/edit-super-heroes.component.html:
<div class="container mt-2"> <legend>Update Item</legend> <form> <div class="mb-3"> <label for="txtName" class="form-label">Name</label> <input type="text" name="name" [(ngModel)]="superHeroes.name" class="form-control" id="txtName" /> </div> <div class="mb-3"> <label for="txtFranchise" class="form-label">Franchise</label> <input type="text" name="txtFranchise" [(ngModel)]="superHeroes.franchise" class="form-control" id="txtFranchise" /> </div> <div class="mb-3"> <label for="txtImageUrl" class="form-label">ImageUrl</label> <input type="text" name="txtImageUrl" [(ngModel)]="superHeroes.imageUrl" class="form-control" id="txtImageUrl" /> </div> <div class="mb-3"> <label for="txtPowers" class="form-label">Powers</label> <textarea class="form-control" name="powers" id="txtPowers" [(ngModel)]="superHeroes.powers" rows="3" ></textarea> </div> <button type="button" (click)="update()" class="btn btn-primary"> Update </button> </form> </div>Now add the 'Edit' button in 'all-super-heroes.component.html'.
Angular_App/src/app/all-super-heroes/all-super-heroes.component.html:
The lang-* class specifies the language file extensions. <div class="container mt-2"> <div class="row mt-2"> <div class="col col-md-4 offset-md-4"> <a class="btn btn-primary" routerLink="/add-super-hero">Create</a> </div> </div> <div class="row row-cols-1 row-cols-md-3 g-2"> <div class="col" *ngFor="let item of superHeroes"> <div class="card"> <img src="{{ item.imageUrl }}" class="card-img-top" alt="..." /> <div class="card-body"> <h5 class="card-title">{{ item.name }}</h5> <p class="card-text"><b>Franchise:</b> {{ item.franchise }}</p> <p class="card-text"><b>Powers:</b> {{ item.powers }}</p> </div> <div class="card-body"> <a class="btn btn-dark" [routerLink]="['edit-super-hero',item._id]"> Edit</a> </div> </div> </div> </div> </div>
- (Line: 19) Configure the 'Edit' button.
(Step 3)
Video session:
Wrapping Up:
Hopefully, I think this article delivered some useful information on NestJS (v9) and Angular(v4). using I love to have your feedback, suggestions, and better techniques in the comment section below.
Refer:
Part-3 | NestJS(v9) | Angular(v14) | MongoDB | CRUD Example
Part-4 | NestJS(v9) | Angular(v14) | MongoDB | CRUD Example
Part- 5| NestJS(v9) | Angular(v14) | MongoDB | CRUD Example
Part-7 | NestJS(v9) | Angular(v14) | MongoDB | CRUD Example
Part-4 | NestJS(v9) | Angular(v14) | MongoDB | CRUD Example
Part- 5| NestJS(v9) | Angular(v14) | MongoDB | CRUD Example
Part-7 | NestJS(v9) | Angular(v14) | MongoDB | CRUD Example
Support Me!
Buy Me A Coffee
PayPal Me
Comments
Post a Comment