How To Perform CRUD Operation Using Array In Angular

In this tutorial, we will learn how to implement CRUD in angular step by step. I have also include shared service concept in this to share data between component.

Angular

–First create new project

open new terminal from menu in VS Code.

Run the following command into command prompt to create new project.

After that you will be prompted “Would you like to add Angular routing? (y/N)” in this write Y to enable routing in project.

It will create new Project in angular folder with all node modules and app component.

–Install bootstrap

–Install PrimeNg

to access primeng control we need to install primeng, run the following command to install it.

npm install primeng
npm install primeicons
npm install @angular/cdk

now you cam access all the control of primeng

–Add Component to Project

To perform add, update, display and delete operation add component for each by doing this we can clear routing concept also. After creating project to navigate to project name,

to add component write command as below in command prompt.

       ng generate component add

By using this command generate component for  delete, gird(to display data) respectively.

–Add shared service to project

Shared service is use to share data among the component.

        ng generate service share

let’s write code to perform crud  with array

First of all add following styles into angular.json file

“node_modules/bootstrap/dist/css/bootstrap.min.css”,
“node_modules/primeng/resources/themes/saga-blue/theme.css”,
“node_modules/primeng/resources/primeng.min.css”,
“node_modules/primeicons/primeicons.css”
Now import all required module to  app-module.ts file. In this we have to register all the components, routing files and services.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import {HttpClientModule} from '@angular/common/http';
import { routingComponent } from './app-routing.module';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AddComponent } from './add/add.component';
import { UpdateComponent } from './update/update.component';
import { GridComponent } from './grid/grid.component';
import { DeleteComponent } from './delete/delete.component';
import { FormsModule,ReactiveFormsModule} from '@angular/forms';

import {TableModule} from 'primeng/table';
import { ButtonModule } from 'primeng/button';
import {DialogModule} from 'primeng/dialog';
import {ConfirmDialogModule} from 'primeng/confirmdialog';
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import {DropdownModule} from 'primeng/dropdown';
import {InputTextModule} from 'primeng/inputtext';
import {CheckboxModule} from 'primeng/checkbox';
import {RadioButtonModule} from 'primeng/radiobutton';
import { ShareService } from './share.service';
import { ConfirmationService } from 'primeng/api';


@NgModule({
  declarations: [
    AppComponent,
    AddComponent,
    UpdateComponent,
    GridComponent,
    DeleteComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    TableModule,
    ButtonModule,
    DialogModule,
    ConfirmDialogModule,
    BrowserAnimationsModule,
    FormsModule,
    DropdownModule,
    ReactiveFormsModule,
    InputTextModule,
    CheckboxModule,
    RadioButtonModule
  ],
  providers: [ShareService,ConfirmationService],
  bootstrap: [AppComponent],
  exports:[routingComponent]
})
export class AppModule { }

app-routing.module.ts

Angular provide routing to easily navigate form one component  to other component.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AddComponent } from './add/add.component';
import { DeleteComponent } from './delete/delete.component';
import { GridComponent } from './grid/grid.component';

const routes: Routes = [{path:'',redirectTo:'grid', pathMatch: 'full'},
{path:'grid',component:GridComponent},
{path:'add',component:AddComponent},
{path: 'delete', component:  DeleteComponent},
{path:'update/:studentId',component:AddComponent}];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
export const routingComponent = [GridComponent,AddComponent,DeleteComponent];

I have added array with path and component where path represent URL and component represent corresponding component html file. I have create

const for all component to apply routing on it.

app-component.html

<router-outlet></router-outlet>

router-outlet is used to showing component html page which we added in routing file.

share.service.ts

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ShareService {
  i: number = 2;
  public id!: number;
  public studentlist = [{ id: 1, firstName: 'Test', lastName: 'test', age: 12, gender: 'Male', hobbies: 'Reading', city: 'Rome' }];

  private updateId = new BehaviorSubject(0);
  updateSubGridData = this.updateId.asObservable();


  constructor() { }

  setId(id: number) {
    this.updateId.next(id);
  }

  getStudentbyID(id: number) {
    return this.studentlist.find(x => x.id == id);
  }
  addStudent(data: any) {
    data.id = this.i++;
    this.studentlist.push(data);
   
  }
  deleteStudent(id: number) {
    this.studentlist.forEach((value, index) => {
      if (value.id == id) this.studentlist.splice(index, 1);
    });
  }
  updateStudent(data: any) {
    debugger
    let index = this.studentlist.findIndex(x => x.id == data.id);
    this.studentlist[index] = data;
  }

}

In above file I have added array with one row value. And also add BehaviorSubject  to share data. We need to import service to which component where we want to share data or update data in array.

grid.component.html

<div class="card">
    <p-table [value]="studlist" styleClass="p-datatable-striped" [rowHover]="true" responsiveLayout="scroll" [rows]="10" [paginator]="true">
        <ng-template pTemplate="caption">
            List of Student
        </ng-template>
        <ng-template pTemplate="header">
            <tr>
                <th colspan="8">
                    <button pButton (click)="addStudent()" class="btn btn-success btnadd">Create New Student</button>
                </th>

            </tr>
            <tr>
                <th>FirstName</th>
                <th>LastName</th>
                <th>Hoobbies</th>
                <th>Gender</th>
                <th>City</th>
                <th>Age</th>
                <th>Action</th>
            </tr>
        </ng-template>
        <ng-template pTemplate="body" let-student>
            <tr>
                <td>{{student.firstName}}</td>
                <td>{{student.lastName}}</td>
                <td>{{student.hobbies}}</td>
                <td>{{student.gender}}</td>
                <td>{{student.city}}</td>
                <td>{{student.age}}</td>

                <td>
                    <button pButton pRipple icon="pi pi-pencil" (click)="updateStudent(student.id)" class="pedit"></button>
                    <button pButton pRipple icon="pi pi-trash" (click)="deleteStudent(student.id)" class="delete"></button>
                </td>
            </tr>
        </ng-template>
    </p-table>

grid.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { ShareService } from '../share.service';


@Component({
  selector: 'app-grid',
  templateUrl: './grid.component.html',
  styleUrls: ['./grid.component.css']
})
export class GridComponent implements OnInit {

  studlist:any;
  id!:number;
  subscription!: Subscription;
  constructor(private shareService:ShareService,private route:Router) { }

  ngOnInit(): void {
    this.studlist = this.shareService.studentlist;
   
  }
  updateStudent(id:number){
    this.id=id;
    this.shareService.setId(this.id)
    this.route.navigateByUrl('update/'+id);
  }
  addStudent(){
    this.shareService.setId(0)
    this.route.navigateByUrl('add');
  }

  ShowDialog(id?: number){

  }
  deleteStudent(id:number){
    this.id=id;
    this.shareService.setId(this.id)
    this.route.navigateByUrl('delete');
  }

}

Here we have to use one component to add and update the student array.

add.component.html

<div class="container mt-5">

    <h3 class="mb-3 col-md-6 title">Student</h3>

    <form [formGroup]="form" (ngSubmit)="submit()">
        <div class="form-group col-md-6 mb-3">
            <label for="firstName">FirstName:</label>
            <input formControlName="firstName" id="firstName" type="text" class="form-control">
            <div *ngIf="f.firstName.touched && f.firstName.invalid" class="alert alert-danger">
                <div *ngIf="f.firstName.errors?.required" class="text-danger">FirstName is required.</div>
            </div>
        </div>
        <div class="form-group col-md-6 mb-3">
            <label for="lastName">LastName:</label>
            <input formControlName="lastName" id="lastName" type="text" class="form-control">
            <div *ngIf="f.lastName.touched && f.lastName.invalid" class="alert alert-danger">
                <div *ngIf="f.lastName.errors?.required" class="text-danger">LastName is required.</div>
            </div>
        </div>
        <div class="form-group col-md-12 mb-3">
            <label for="hobbies">Hobbies:</label>
            <div [style.display]="'flex'" class="col-md-6">
                <div *ngFor="let hb of Hobbies; let i=index" class="col-md-3">
                    <label>
                  <input type="checkbox"  [value]="hb.value" [checked]="hb.checked" (change)="onCheckboxChange($event)" formArrayName="hobbies"/>
                  {{hb.name}}
                </label>
                </div>
            </div>
            <div *ngIf="this.form.controls['hobbies'].touched" class="alert alert-danger">
                <div *ngIf="this.form.controls['hobbies'].errors?.required" class="alert alert-danger">
                    Select at least one hobby.
                </div>
            </div>
        </div>
        <div class="form-group col-md-12 mb-3">
            <label for="gender">Gender:</label>
            <div [style.display]="'flex'">
                <div>
                    <input id="Male" type="radio" value="Male" name="gender" formControlName="gender">
                    <label for="Male" class="col-md-6">Male</label>
                </div>
                <div>
                    <input id="Female" type="radio" value="Female" name="gender" formControlName="gender">
                    <label for="Female" class="col-md-6">Female</label>
                </div>
            </div>
            <div *ngIf="f.gender.touched && f.gender.invalid" class="alert alert-danger">
                <div *ngIf="f.gender.errors?.required" class="text-danger">Select Gender</div>
            </div>

        </div>
        <div class="form-group col-md-6 mb-3">
            <label for="city">City:</label>
            <select class="custom-select form-control" name="city" formControlName="city">
                <option value="" selected>----Select City----</option>
                <option *ngFor="let city of cities"  [ngValue]="city.name">{{city.name}}</option>
            </select>
            <div *ngIf="f.city.touched && f.city.invalid" class="alert alert-danger">
                <div *ngIf="f.city.errors?.required" class="text-danger">City is required.</div>
            </div>
        </div>
        <div class="form-group col-md-6 mb-3">
            <label for="age">Age:</label>
            <input formControlName="age" id="age" type="text" class="form-control">
            <div *ngIf="f.age.touched && f.age.invalid" class="alert alert-danger">
                <div *ngIf="f.age.errors?.required" class="text-danger">Age is required.</div>
                <div *ngIf="f.age.errors?.pattern" class="text-danger">Age must be in number.</div>
            </div>
        </div>
        <div class="col-md-6">
            <button class="btn btn-primary" type="submit" style="float:right">Submit</button>
            <a href="#" routerLink="/grid" class="btn btn-primary" [ngStyle]="styleClass">Back</a>

        </div>
    </form>
</div>

add.component.ts

import { Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { ShareService } from '../share.service';
import { City, Stud } from '../stud';

@Component({
  selector: 'app-add',
  templateUrl: './add.component.html',
  styleUrls: ['./add.component.css']
})
export class AddComponent implements OnInit {

  studentData!: Stud;
  form!: FormGroup;
  selectedHobbies = [];
  selectedCityName: any;
  cities!: City[];
  Hobbies = [
    { name: 'Reading', value: 'Reading', checked: false },
    { name: 'Music', value: 'Music', checked: false },
    { name: 'Cricket', value: 'Cricket', checked: false },
    { name: 'Traveling', value: 'Traveling', checked: false },
  ];
  public styleClass = {
    float: "right",
    marginRight: "30px"
  }
  subscription!: Subscription;
  public studentinfo!: any;

  constructor(private fb: FormBuilder, private shareService: ShareService, private route: Router) { }

  ngOnInit(): void {
    debugger
    this.form = this.fb.group({
      firstName: ['', [Validators.required]],
      lastName: ['', [Validators.required]],
      hobbies: this.fb.array([]),
      gender: ['', [Validators.required]],
      age: ['', Validators.compose([Validators.required, Validators.pattern('[0-9+]*')])],
      city: ['', [Validators.required]],
      id: ['']
    });
    this.cities = [
      { name: 'New York', code: 'NY' },
      { name: 'Rome', code: 'RM' },
      { name: 'London', code: 'LDN' },
      { name: 'Istanbul', code: 'IST' },
      { name: 'Paris', code: 'PRS' }];

    this.subscription = this.shareService.updateSubGridData.subscribe(id => {
      console.log(id);
      this.studentinfo = this.shareService.getStudentbyID(id);
      console.log(this.studentinfo);
      
      this.setvalue();
    })

  }
  ngOnDestroy() {
    this.subscription.unsubscribe();
  } 
  get f() {
    return this.form.controls;
  }
  setvalue() {

    this.form.setControl('hobbies', this.fb.array((this.studentinfo.hobbies).split(',') || []));
    this.Hobbies.forEach(res => {
      if (this.form.value.hobbies.includes(res.value)) {
        res.checked = true
      }
    })
    this.form.patchValue({
      firstName: this.studentinfo.firstName,
      lastName: this.studentinfo.lastName,
      gender: this.studentinfo.gender,
      age: this.studentinfo.age,
      city: this.studentinfo.city,
      id: this.studentinfo.id,
    });

  }

  onCheckboxChange(e: any) {
    const hobbies: FormArray = this.form.get('hobbies') as FormArray;
    if (e.target.checked) {

      hobbies.push(new FormControl(e.target.value));
    } else {

      const index = hobbies.controls.findIndex(x => x.value === e.target.value);

      hobbies.removeAt(index);

    }
  }
  submit() {
    debugger
    this.form.value.hobbies = this.form.value.hobbies.toString();
    if (this.studentinfo == undefined) {
      this.shareService.addStudent(this.form.value);
    }
    else {
      this.form.patchValue({
        id: this.studentinfo.id,
      })
      this.form.value.hobbies = this.form.value.hobbies.toString();
      this.shareService.updateStudent(this.form.value)
    }

    this.route.navigateByUrl('grid');
  }
}

 delete.component.html

<h1>delete</h1>
<p-confirmDialog header="Confirmation" icon="pi pi-exclamation-triangle"></p-confirmDialog>

delete.component.ts

@Component({
  selector: 'app-delete',
  templateUrl: './delete.component.html',
  styleUrls: ['./delete.component.css']
})
export class DeleteComponent implements OnInit {
  subscription!:Subscription;

  constructor(private confirmationService:ConfirmationService,private shareService:ShareService,private route:Router ) { }

  ngOnInit(): void {
    this.subscription = this.shareService.updateSubGridData.subscribe(id => {
      console.log(id);
      this.confirmationService.confirm({
        message: 'Are you sure you want to delete the selected User?',
        header: 'Confirm',
        icon: 'pi pi-exclamation-triangle',
        accept: () => {
          this.shareService.deleteStudent(id)
          this.route.navigateByUrl('grid');
        }
      });
    })
    
  }
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

}

In this tutorial, we have seen a simple way to create a CRUD operation using an array with using concept of shared service.

OUTPUT :

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories