Home / Angular / Build Employee Management System from scratch with Two Way Data Binding in Angular 18 and .NET 9

Build Employee Management System from scratch with Two Way Data Binding in Angular 18 and .NET 9

Two-way data binding is a fundamental concept in modern web development, enabling seamless synchronization between the user interface and data models. This tutorial demonstrates how to build a robust employee management system utilizing Angular for the frontend and .NET 9 for the backend. By leveraging two-way data binding, we ensure that any changes in the UI are instantly reflected in the backend and vice versa, creating a dynamic and interactive application.

The project integrates SQL Server for data storage, providing a real-world scenario for managing employee data efficiently. We’ll cover everything from setting up a new project in Visual Studio 2022 to implementing two-way data binding for creating and displaying employee records dynamically. This guide is ideal for developers looking to master full-stack development with Angular and .NET technologies while understanding the power of two-way data binding.

Prerequisites

Before starting this project, ensure you have the following tools and technologies installed on your machine:

  1. Visual Studio 2022 (with .NET and ASP.NET workload installed).
  2. Node.js (latest stable version).
  3. Angular CLI (install using npm install -g @angular/cli).
  4. SQL Server (Express or Developer Edition).
  5. Basic knowledge of Angular, .NET, and SQL Server.

Learn more about angular step Angular project Setup Step by Step Practical Tutorial – Full Stack Tutorials Hub

What is Two Way Data Binding in Angular?

Two-way data binding is a mechanism where changes in the UI are automatically reflected in the model (data) and vice versa. It establishes a direct synchronization between the view and the underlying data model. This means:

  • When the user updates a value in the UI (e.g., a form input), the corresponding model is updated automatically.
  • When the model is updated programmatically, the UI reflects those changes instantly.

This makes it easier to manage dynamic, interactive interfaces as it eliminates the need for manual DOM updates and simplifies the flow of data in the application.

Project Setup

Backend (.NET 9)

  1. Open Visual Studio 2022.
  2. Create a new ASP.NET Core Web API project.
  3. Name the project EmployeeManagement and select .NET 9 as the target framework.

Frontend (Angular)

  1. Open a terminal.
  2. Create a new Angular project:ng new employee-management
  3. Navigate to the project folder:cd employee-management
  4. Add Bootstrap for styling:npm install bootstrap
  5. Update angular.json to include Bootstrap:

Application Structure

1. Backend API

Employee Model

Create a new folder Models in the project and add a file Employee.cs:

namespace EmployeeManagement.Models
{
    public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Department { get; set; }
        public string Email { get; set; }
    }
}

Employee Controller

Add a new controller named EmployeeController:

using Microsoft.AspNetCore.Mvc;
using EmployeeManagement.Models;
using System.Collections.Generic;

namespace EmployeeManagement.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class EmployeeController : ControllerBase
    {
        private static List<Employee> employees = new List<Employee>();

        [HttpGet]
        public IActionResult GetAllEmployees()
        {
            return Ok(employees);
        }

        [HttpPost]
        public IActionResult AddEmployee(Employee employee)
        {
            employee.Id = employees.Count + 1;
            employees.Add(employee);
            return Ok(employee);
        }
    }
}

In appsettings.json, configure the connection string:

"ConnectionStrings": {
  "DefaultConnection": "Server=your_server;Database=EmployeeDB;Trusted_Connection=True;"
}

Add Entity Framework Core to the project:

dotnet add package Microsoft.EntityFrameworkCore.SqlServer

Update Program.cs to add the database context:

using Microsoft.EntityFrameworkCore;
using EmployeeManagement.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddDbContext<EmployeeContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseAuthorization();

app.MapControllers();

app.Run();

Create EmployeeContext:

using Microsoft.EntityFrameworkCore;

namespace EmployeeManagement.Models
{
    public class EmployeeContext : DbContext
    {
        public EmployeeContext(DbContextOptions<EmployeeContext> options) : base(options) { }

        public DbSet<Employee> Employees { get; set; }
    }
}

Run migrations:

dotnet ef migrations add InitialCreate
dotnet ef database update

2. Frontend (Angular)

Create Employee Component

Run the following command to generate a component

ng generate component employee

Employee Model

Create a file employee.model.ts:

export interface Employee {
  id: number;
  name: string;
  department: string;
  email: string;
}

Employee Service

Create a service:

ng generate service employee

Update employee.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Employee } from './employee.model';

@Injectable({
  providedIn: 'root',
})
export class EmployeeService {
  private apiUrl = 'https://localhost:5001/api/Employee';

  constructor(private http: HttpClient) {}

  getEmployees(): Observable<Employee[]> {
    return this.http.get<Employee[]>(this.apiUrl);
  }

  addEmployee(employee: Employee): Observable<Employee> {
    return this.http.post<Employee>(this.apiUrl, employee);
  }
}

How Two-Way Data Binding is Implemented in This Project

Two Way Data Binding in Angular Syntax

In Angular, two-way data binding is achieved using the [(ngModel)] directive. The [(ngModel)] directive binds an input field to a variable in the component, allowing data to flow in both directions:

  • From the variable to the UI.
  • From the UI back to the variable.
<input type="text" [(ngModel)]="employee.name" />

Here:

  • Any change in the employee.name property will automatically update the input field.
  • Any user input in the field will update the employee.name property.

In this project, two-way data binding is used in the Employee Form to bind the form fields to the employee model in the Angular component

Employee Component HTML

Update employee.component.html:

<div class="container mt-5">
  <h2>Employee Form</h2>
  <form (ngSubmit)="addEmployee()">
    <div class="mb-3">
      <label for="name" class="form-label">Name</label>
      <input type="text" id="name" [(ngModel)]="employee.name" name="name" class="form-control" required />
    </div>
    <div class="mb-3">
      <label for="department" class="form-label">Department</label>
      <input type="text" id="department" [(ngModel)]="employee.department" name="department" class="form-control" required />
    </div>
    <div class="mb-3">
      <label for="email" class="form-label">Email</label>
      <input type="email" id="email" [(ngModel)]="employee.email" name="email" class="form-control" required />
    </div>
    <button type="submit" class="btn btn-primary">Add Employee</button>
  </form>

  <h3 class="mt-5">Employee List</h3>
  <table class="table">
    <thead>
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Department</th>
        <th>Email</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let emp of employees">
        <td>{{ emp.id }}</td>
        <td>{{ emp.name }}</td>
        <td>{{ emp.department }}</td>
        <td>{{ emp.email }}</td>
      </tr>
    </tbody>
  </table>
</div>

n this code:

  • Each [(ngModel)] directive binds the input field (name, department, and email) to the corresponding property in the employee object.
  • Any changes made by the user in these fields are immediately reflected in the employee object in the component.

Employee Component TS

Update employee.component.ts:

import { Component, OnInit } from '@angular/core';
import { Employee } from '../employee.model';
import { EmployeeService } from '../employee.service';

@Component({
  selector: 'app-employee',
  templateUrl: './employee.component.html',
  styleUrls: ['./employee.component.css'],
})
export class EmployeeComponent implements OnInit {
  employee: Employee = { id: 0, name: '', department: '', email: '' };
  employees: Employee[] = [];

  constructor(private employeeService: EmployeeService) {}

  ngOnInit(): void {
    this.loadEmployees();
  }

  loadEmployees(): void {
    this.employeeService.getEmployees().subscribe((data) => (this.employees = data));
  }

  addEmployee(): void {
    this.employeeService.addEmployee(this.employee).subscribe((newEmployee) => {
      this.employees.push(newEmployee);
      this.employee = { id: 0, name: '', department: '', email: '' };
    });
  }
}

Here:

  • The employee object holds the data for the form.
  • When the user submits the form, the addEmployee() method is called, which sends the employee object to the backend API.

Run the Application

  • Start the backend API:dotnet run
  • Start the Angular application:ng serve
  • Navigate to http://localhost:4200 to see the application in action.

Displaying the Employee List

Two-way data binding also plays a role in reflecting updated data on the UI. After adding a new employee, the employees array is updated, and the UI automatically refreshes to display the new list.

HTML (Employee List)
<tr *ngFor="let emp of employees">
  <td>{{ emp.id }}</td>
  <td>{{ emp.name }}</td>
  <td>{{ emp.department }}</td>
  <td>{{ emp.email }}</td>
</tr>

In this snippet:

  • The employees array is bound to the table rows using *ngFor.
  • Any updates to the employees array (e.g., adding a new employee) are immediately reflected in the table.

Why Two-Way Data Binding is Important

  1. Simplifies Data Management: Two-way binding eliminates the need to manually synchronize data between the UI and the model, reducing boilerplate code.
  2. Dynamic UI Updates: Changes in data are immediately visible in the UI, improving user experience.
  3. Cleaner Code: Reduces the risk of bugs caused by inconsistent data handling.

In this project, two-way data binding ensures seamless synchronization between the employee form inputs and the data model, making it easier to manage the state of the form and reflect changes in the employee list dynamically.

External Resources

Here are some helpful external resources.

  1. Understanding Angular NgModel
  2. SQL Server Connection in .NET Core

FAQ

Scroll to Top