Angular Material CRUD Example


Download Material Angular-CRUD Example

In this tutorial, we are going to learn how to build a Material CRUD application in Angular 14. CRUD operations stands for the four functions create, read, update, and delete in computer programming. Firstly we create API that fetch data from SQL Server table. Use that API in angular project to add, read, update and delete data. We will create a employee list on that list we can add new employee, update employee and delete employee. So this tutorial explains all the CRUD operations step by step. Here, we have divided the task mainly in 3 parts as following:

  1. SQL Server
  2. .NET API
  3. Material + Angular 14

Part 1: SQL Server

Open SQL Server Management Studio, create a database named EmployeeDB and in this database create a table. Give that table a name like Employees. The below script to create Employees table.

USE [EmployeeDB]
GO

/****** Object: Table [dbo].[Employees] Script Date: 05-12-2022 00:40:43 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Employees](
[Id] [int] IDENTITY(1,1) NOT NULL,
[EmployeeType] [int] NOT NULL,
[Name] [nvarchar](max) NOT NULL,
[Designation] [nvarchar](max) NOT NULL,
[Salary] [int] NOT NULL,
CONSTRAINT [PK_dbo.Employees] PRIMARY KEY CLUSTERED 
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

Part 2: .NET API

Open Visual Studio and create a new project.

Angular Material

Now Click on the next button and give project name EmployeeResgistration.

Angular Material

Now click on the Next button and select API looks like as:

Angular Material

Now click on the create button. Project structure looks like:

Angular Material

Now open Web.Config file and add connection string inside connectionStrings section.

<add name="EmployeeDb" connectionString="Server=DESKTOP-G82VNVU;Initial Catalog=EmployeeDB; Persist Security Info=True; Integrated Security=True" providerName="System.Data.SqlClient" />

Now Add a employeeContext file and add the following code inside it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using ResgistrationEmployee.Models;

namespace ResgistrationEmployee
{
    public class EmployeeContext : DbContext
    {
        private object _dsDbContext;

        public EmployeeContext() : base("EmployeeDb")
        {

        }
        public DbSet Employees { get; set; }
    }
}

Now create a employee controller and add the following code to the controller.

using EmployeeResgistration.Models;
using Microsoft.AspNetCore.Cors;
using ResgistrationEmployee;
using ResgistrationEmployee.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace EmployeeResgistration.Controllers
{
    [Route("api/employee")]
    public class EmployeeController : ApiController
    {
        EmployeeContext _dbContext = new EmployeeContext();

        [HttpGet]
        public IEnumerable GetAllEmployees()
        {
            return _dbContext.Employees.ToList();
        }

        [HttpGet]
        public Employee GetEmployeesbyid(int id)
        {
            return _dbContext.Employees.First(x => x.Id == id); 
        }

        [HttpPost]
        public IHttpActionResult Post(Employee employee)
        {
            try
            {
                _dbContext.Employees.Add(employee);
                _dbContext.SaveChanges();
                return Ok(new { Message =""});
            }
            catch (Exception ex)
            {

                return BadRequest();
            }

        }

        [HttpDelete]
        public IHttpActionResult Delete(int id)
        {
            try
            {
                var details = _dbContext.Employees.FirstOrDefault(x => x.Id == id);
                _dbContext.Employees.Remove(details);
                _dbContext.SaveChanges();
                return Ok();
            }
            catch (Exception)
            {

                return BadRequest();
            }

        }
       
        [HttpPut]
        public IHttpActionResult Put(Employee[] employee)
        {
            try
            {
                foreach (var item in employee)
                {
                    var details = _dbContext.Employees.FirstOrDefault(x => x.Id == item.Id);
                    details.Designation = item.Designation;
                    details.EmployeeType = item.EmployeeType;
                    details.Salary = item.Salary;
                    details.Name = item.Name;
                    _dbContext.SaveChanges();
                }
                return Ok();
            }
            catch (Exception)
            {

                return BadRequest();
            }

        }
    }
}

Now run the API application and will see GET, POST, DELETE and PUT API now running.

Angular Material

Part 3: Material + Angular 14

1. Create an Angular application

The following command uses the Angular CLI to create a Angular application. The application name in the following example is angularcrud.

ng new EmployeeRegistration

Adding components for routing

The following command uses the Angular CLI to create component one by one. The components name in the following example is create, edit, view.

ng generate component registrationform
ng generate component registrationtable

Now we create a shared folder which have two .ts file named service.service.ts and employee-model.ts. The project strcture looks like that:

Image-Projectfile

After creating our components parts,Open the employee-model.ts file inside the shared folder and adding the following code.

  export class EmployeeModel {
    id: number=0
    employeeType: number=0
    name: string=""
    designation: string=""
    salary: number=0
}

Now adding the following code on service.service.ts to fetch data from API.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { EmployeeModel } from './employee-model';
import { Observable } from 'rxjs';
@Injectable({
  providedIn: 'root'
})
export class ServiceService {

  constructor(private http: HttpClient) { }

  getEmployeeList() {
    return this.http.get(environment.baseUrl);
  }
  saveEmplopyeeDetails(formarr: any) {
    console.log(formarr);
    return this.http.put(`${environment.baseUrl}`, formarr);
  }

  deleteRecord(id) {
    return this.http.delete(`${environment.baseUrl}/?id=${id}`);
  }

  addformdata(form:EmployeeModel):Observable{
    return this.http.post(`${environment.baseUrl}`,form);
  };
}

Now add the following code on app-routing.module.ts file to rout all the components.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { RegistrationTableComponent } from './registration-table/registration-table.component';
import { RegistrationFormComponent } from './registration-form/registration-form.component';

const routes: Routes = [
  {path:"",component:RegistrationFormComponent},
  {path:"table",component:RegistrationTableComponent},
  {path:"form",component:RegistrationFormComponent}
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
export const routingComponent=[RegistrationFormComponent,RegistrationTableComponent];

Now add the following code on app.module.ts file to rout all the components.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { AppRoutingModule,routingComponent } from './app-routing.module';
import { AppComponent } from './app.component';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule} from '@angular/material/checkbox';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 
import { HttpClientModule } from '@angular/common/http';
import {MatToolbarModule} from '@angular/material/toolbar';
@NgModule({
  declarations: [
    AppComponent,
    routingComponent
  ],
  imports: [
    BrowserAnimationsModule,
    BrowserModule,
    AppRoutingModule,
    AppRoutingModule,
    MatSelectModule,
    MatButtonModule,
    ReactiveFormsModule,
    HttpClientModule,
    MatInputModule,
    MatCheckboxModule,
    MatToolbarModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now add the following code on registration-form.component.html component file.

<div class="container pt-3">
<form [formGroup]="reactiveform" (ngSubmit)="onSubmit()"> 
<div class="row">
<mat-form-field>
<div class="col-12 col-sm-12 col-md-6 col-lg-3 col-xl-3">
<mat-label>Select Employee Type</mat-label>
</div>
<div class="col-12 col-sm-12 col-md-6 col-lg-9 col-xl-9">
<mat-select formControlName="employeeType">
<mat-option value="">---Select Employee Type---</mat-option>
<mat-option value="0">Permanent</mat-option>
<mat-option value="1">Contract</mat-option>
</mat-select>
</div>
</mat-form-field>
</div>
<div class="row">
<mat-form-field>
<div class="col-12 col-sm-12 col-md-6 col-lg-3 col-xl-3">
<input matInput formControlName="name" placeholder="Enter Name">
</div>
<div class="col-12 col-sm-12 col-md-6 col-lg-9 col-xl-9">
<mat-error *ngIf="reactiveform.get('name').touched && reactiveform.get('name').invalid">
<mat-error *ngIf="reactiveform.get('name').errors.required">
Name is required.
</mat-error>
</mat-error>
</div>
</mat-form-field>
</div>
<div class="row">
<mat-form-field>
<div class="col-12 col-sm-12 col-md-6 col-lg-3 col-xl-3">
<input matInput formControlName="designation" placeholder="Enter Designation">
</div>
<div class="col-12 col-sm-12 col-md-6 col-lg-9 col-xl-9">
<mat-error *ngIf="reactiveform.get('designation').touched && reactiveform.get('designation').invalid">
<mat-error *ngIf="reactiveform.get('designation').errors.required">
Designation is required.
</mat-error>
</mat-error>
</div>
</mat-form-field>
</div>
<div class="row">
<mat-form-field>
<div class="col-12 col-sm-12 col-md-6 col-lg-3 col-xl-3">
<input matInput formControlName="salary" placeholder="Enter Salary">
</div>
<div class="col-12 col-sm-12 col-md-6 col-lg-9 col-xl-9">
<mat-error *ngIf="reactiveform.get('salary').touched && reactiveform.get('salary').invalid">
<mat-error *ngIf="reactiveform.get('salary').errors.required">
Salary is required.
</mat-error>
</mat-error>
</div>
</mat-form-field>
</div>
<div class="col 12 col sm 12 col md 4 col lg 3">
<input mat-raised-button color="primary" type="submit"/>
</div>
</form>
</div>

Now add the following code on  registration-form.component.ts component file.

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ServiceService } from '../shared/service.service';

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

  reactiveform: FormGroup;
  empList: any;
  constructor(private _service: ServiceService,
    private fb: FormBuilder
  ) { }

  ngOnInit(): void {
    this.reactiveform = this.fb.group({
      id: ['0', Validators.required],
      employeeType: ['', Validators.required],
      name: ['', Validators.required],
      designation: ['', Validators.required],
      salary: ['', Validators.required],
    });
  }
  onSubmit() {
    this._service.addformdata(this.reactiveform.value).subscribe({
      next: () => {
        alert("data saved");
      },
      error: error => {

      }
    })
  }
}

Now add the following code on registration-table.component.html component file.

<div class="grid-table">
<div class="thead">
<div class="tr">
<div class="td">Sno</div>
<div class="td">Employee Type</div>
<div class="td">Name</div>
<div class="td">Designation</div>
<div class="td">Salary</div>
<div class="td">Action</div>
</div>
</div>
<div class="tbody">
<form [formGroup]="fdata" class="tr" *ngFor="let fdata of reactivearray.controls">
<div class="td">
<section class="example-section">
<mat-checkbox class="example-margin" (change)="onCheckboxChange(fdata.value,$event.checked)"></mat-checkbox>
</section>
</div>
<td class="td">
<mat-form-field>
<mat-label>Select Employee Type</mat-label>
<mat-select formControlName="employeeType">
<mat-option value="">---Select Employee Type---</mat-option>
<mat-option *ngFor="let item of eType" [value]="item.id">{{item.name}}</mat-option>
</mat-select>
</mat-form-field>
</td>
<div class="td">
<mat-form-field>
<mat-label>Name</mat-label>
<input matInput formControlName="name" placeholder="Enter Name">
<mat-error *ngIf="reactiveform.get('name').touched && reactiveform.get('name').invalid">
<mat-error *ngIf="reactiveform.get('name').errors.required">
Name is required.
</mat-error>
</mat-error>
</mat-form-field>
</div>
<div class="td">
<mat-form-field>
<mat-label>Designation</mat-label>
<input matInput formControlName="designation" placeholder="Designation">
<mat-error
*ngIf="reactiveform.get('designation').touched && reactiveform.get('designation').invalid">
<mat-error *ngIf="reactiveform.get('designation').errors.required">
Designation is required.
</mat-error>
</mat-error>
</mat-form-field>
</div>
<div class="td">
<mat-form-field>
<mat-label>Salary</mat-label>
<input matInput placeholder="Salary" formControlName="salary">
<mat-error *ngIf="reactiveform.get('salary').touched && reactiveform.get('salary').invalid">
<mat-error *ngIf="reactiveform.get('salary').errors.required">
Salary is required.
</mat-error>
</mat-error>
</mat-form-field>
</div>
<div class="td">
<div class="col 12 col sm 12 col md 4 col lg 3">
<input mat-raised-button color="primary" type="submit" value="Delete" (click)="deletebtn(fdata.value)" />
</div>
</div>
</form>
</div>
</div>
<input type="button" value="Save" (click)="onclick()">

Now add the following code on registration-table.component.ts component file.

import { Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { ServiceService } from '../shared/service.service';


@Component({
  selector: 'app-registration-table',
  templateUrl: './registration-table.component.html',
  styleUrls: ['./registration-table.component.css']
})
export class RegistrationTableComponent implements OnInit {
  
  reactiveform: FormGroup;
  employeeList: any;
  reactivearray: FormArray = this.fb.array([]);
  updateArray: FormArray = this.fb.array([]);
  employeeobject: any;
  eType: any;


  constructor(private fb: FormBuilder,
    private _service: ServiceService) { }

  ngOnInit(): void {
    this.eType = [
      { id: 1, name: 'Permanent' },
      { id: 2, name: 'Contract' }
    ]

    this.reactiveform = this.fb.group({
      id: ['0', Validators.required],
      employeeType: ['0', Validators.required],
      name: ['', Validators.required],
      designation: ['', Validators.required],
      salary: ['', Validators.required],
    })

    this._service.getEmployeeList().subscribe(
      res => {
        (res as []).forEach((data: any) => {
          let eid = this.eType.filter(x => x.id == data.EmployeeType);
          
          this.reactivearray.push(this.fb.group({
            id: [data.Id, Validators.required],
            employeeType: [eid[0].id, Validators.required],
            name: [data.Name, Validators.required],
            designation: [data.Designation, Validators.required],
            salary: [data.Salary, Validators.required],
          }))
        })
      }
    );
  }

  onCheckboxChange(e, status) {
    console.warn(status);
    if (status == true) {
      this.updateArray.push(
        this.fb.group({
          id: [e.id, Validators.required],
          employeeType: [e.employeeType, Validators.required],
          name: [e.name, Validators.required],
          designation: [e.designation, Validators.required],
          salary: [Number(e.salary), Validators.required],
        }));
    }
    else {
      let index = this.updateArray.value.findIndex(x => x.Id === e.id);
      this.updateArray.removeAt(index);
    }

    console.log(this.updateArray);
  }
  onclick() {
    console.log(this.updateArray.value);
    this._service.saveEmplopyeeDetails(this.updateArray.value).subscribe(
      res => {
        window.location.reload()  
      }
    );
  }
  deletebtn(e) {
    this._service.deleteRecord(e.id).subscribe(res => {
      window.location.reload();
    });
  }
}

Now run the web api project first and after that run the angular project. Employee registration form will open to add employee.

Angular Material

Now click on the Employee Details menu to see the registered employee in material table that is also stored in SQL Table Employees.

Angular Material

Now enter name as Gaurav Kumar in place of Gaurav and check the check box against record which you want to update.

Angular Material

Now click on the save button to update. see the table with updated record.

Angular Material

Now select checkbox which record need to delete

Angular Material

Now click on delete button to delete record. See the table after delete record.

Angular Material

Download Material Angular-CRUD Example


Prev Next