Hello friends, welcome back to my blog. Today this blog post I will tell you, Angular 16+ Crud using Json Server working Example.
Angular 16 came and if you are new then you must check below two links:
Friends now I proceed onwards and here is the working code snippet and please use carefully this to avoid the mistakes:
1. Firstly friends we need fresh angular 16 setup and for this we need to run below commands but if you already have angular 16 setup then you can avoid below commands. Secondly we should also have latest node version installed on our system:
npm install -g @angular/cli ng new angulardemo //Create new Angular Project cd angulardemo // Go inside the Angular Project Folder ng g c api //will create api crud component ng g s services/recipe //will create services files ng g i models/recipe //will create interface file npm i bootstrap npm i @popperjs/core
2. Now guys we need to add below code inside angulardemo/angular.json files to call bootstrap 5 script and styles:
"styles": [ ... "node_modules/bootstrap/dist/css/bootstrap.min.css" ], "scripts": [ "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js" ]
3. Now guys we need to add below code inside src/app/api/api.component.html file:
<div class="container w-50 p-5"> <h1 class="text-center pb-4 ">Add, Update and Delete a Recipe </h1> <form #isFormValid="ngForm" [formGroup]="recipeFormGroup" class="form-group"> <div class="mb-3"> <!-- name --> <label for="name" class="form-label">Name</label> <input type="text" class="form-control" name="name" formControlName="name" id="name" placeholder="Enter Recipe Name"> <!-- name errors --> <div *ngIf="name?.touched && name?.invalid"> <small class="text-danger" *ngIf="name?.errors?.['required']">Name is required</small> <small class="text-danger" *ngIf="name?.errors?.['minlength']">Name is too short</small> </div> </div> <!-- price --> <div class="mb-3"> <label for="price" class="form-label">Price</label> <input type="price" class="form-control" name="price" formControlName="price" id="price" placeholder="price"> <!-- price errors --> <div *ngIf="price?.touched && price?.invalid"> <small class="text-danger" *ngIf="price?.errors?.['required']">Price is required</small> <small class="text-danger" *ngIf="price?.errors?.['pattern']">Price is invalid</small> </div> </div> <!-- create(Add) or Update(put) --> <div class="mb-3"> <!-- create --> <button *ngIf="!addOrPut" (click)="postRecipe()" class="form-control btn btn-dark hvr" [disabled]="!isFormValid.valid">Add</button> <!-- Update --> <button *ngIf="addOrPut" (click)="putRecipe()" class="form-control btn btn-warning hvr" [disabled]="!isFormValid.valid">Update</button> </div> </form> <div *ngIf="array.length == 0" class="alert alert-warning text-center">Empty array</div> </div> <div *ngIf="array.length != 0" class="container w-50"> <table class="table table-striped table-bordered"> <thead> <tr> <th>#Id</th> <th>Name</th> <th>Price (MAD)</th> <th>Edit</th> <th>Delete</th> </tr> </thead> <tbody> <tr *ngFor="let eachCmd of array"> <td scope="row">{{eachCmd.id}}</td> <td>{{eachCmd.name}}</td> <td>{{eachCmd.price}}</td> <td><button (click)="editRecipe(eachCmd)" class="btn btn-warning">Update</button></td> <td><button (click)="deleteRecipe(eachCmd.id)" class="btn btn-danger">Delete</button></td> </tr> </tbody> </table> </div>
4. Now guys we need to add below code inside src/app/api/api.component.ts file:
import { Component, OnInit } from '@angular/core'; import { RecipeDto } from '../models/recipe.interface'; import { RecipeService } from '../services/recipe.service'; import { FormGroup, FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-api', templateUrl: './api.component.html', styleUrls: ['./api.component.css'] }) export class ApiComponent implements OnInit { array: RecipeDto[] = new Array<RecipeDto>(); recipeFormGroup: FormGroup = new FormGroup({ id: new FormControl<number>(+''), name: new FormControl<string>('', [ Validators.required, Validators.minLength(3) ]), price: new FormControl<number>(+'', [ Validators.required, Validators.pattern('[0-9]*'), ]) }); get name() { return this.recipeFormGroup.get('name'); } get price() { return this.recipeFormGroup.get('price'); } addOrPut = false; constructor(private recipeService:RecipeService) { } ngOnInit(): void { this.getRecipe(); } getRecipe() { this.recipeService.getAll() .subscribe((data: RecipeDto[]) =>{ this.array = data; }) } deleteRecipe(id: number){ this.recipeService.delete(id).subscribe( () => {this.array = this.array.filter( (aRecipe) => aRecipe.id != id) }) } postRecipe(){ if(!confirm(`api.component.ts:58 -> Did you run the JSON-SERVER ? if yes please comment this line`)) alert(`You should run the json-server (read README file) ^^`); this.recipeService.post(this.recipeFormGroup.value) /* this.recipeFormGroup.value is equivalent to: { name, price } */ .subscribe( (eachRecipe: any)=>{ this.array = [eachRecipe, ...this.array]; this.clearInputs(); }) } // make inputs empty clearInputs(){ this.recipeFormGroup.reset({ name: '', price: +'' }); } // edit recipeService editRecipe(eachRecipe: RecipeDto){ this.recipeFormGroup.get('id')?.setValue(eachRecipe.id); this.recipeFormGroup.get('name')?.setValue(eachRecipe.name); this.recipeFormGroup.get('price')?.setValue(eachRecipe.price); this.addOrPut=true; } // update recipeService putRecipe(){ this.recipeService.updateRecipe(this.recipeFormGroup.value) .subscribe( () => { this.clearInputs(); this.getRecipe(); this.addOrPut = false; }) } }
5. Now guys we need to add below code inside src/app/api/api.component.css file:
.hvr:hover{ background-color: rgb(173, 201, 192); color:black; }
6. Now guys we need to add below code inside src/app/models/recipe.interface.ts file:
export class RecipeDto { id!: number; name!: string; price!: number; }
7. Now guys we need to add below code inside src/app/services/recipe.service.ts file:
import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { environment } from 'src/environments/environment.prod'; import { RecipeDto } from '../models/recipe.interface'; @Injectable({ providedIn: 'root' }) export class RecipeService { urlApi= environment.api; constructor(private http:HttpClient) { } // GET all getAll(){ return this.http.get<RecipeDto[]>(this.urlApi); } // DELETE one delete(id: number){ return this.http.delete(`${this.urlApi}/${id}`); } // CREATE one post(recipe: RecipeDto){ return this.http.post<RecipeDto>(this.urlApi, recipe); } // UPDATE one updateRecipe(recipe: RecipeDto){ return this.http.put(`${this.urlApi}/${recipe.id}`, recipe); } // search by id search(id: number){ return this.http.get<RecipeDto>(`${this.urlApi}/${id}`); //${id} } }
8. Now guys we need to add below code inside src/environments/environment.prod.ts file:
export const environment = { production: true, api: `http://localhost:42400/recipes` };
9. Now guys please create `fakeDatabase.json` file on the project root and add below demo data inside it:
{ "recipes": [ { "id": 1, "name": "Butter Chicken", "price": "800" }, { "id": 2, "name": "Mutton", "price": "980" } ] }
10. Now guys inside package.json file add below line of code under scripts tag to run json server:
also run command npm json-server inside your terminal
"scripts": { ... "json-server": "json-server --watch fakeDatabase.json --port 42400" },
11. Guys in the end we need to add below code inside src/app/app.component.html file
<app-api></app-api>
Friends in the end must run ng serve command into your terminal to run the angular 17 project(localhost:4200).
Now we are done friends. If you have any kind of query, suggestion and new requirement then feel free to comment below.
Note: Friends, In this post, I just tell the basic setup and things, you can change the code according to your requirements.
I will appreciate that if you will tell your views for this post. Nothing matters if your views will be good or bad because with your views, I will make my next posts more good and helpful.
Jassa
Thanks 🙂
Recent Comments