Step-by-Step: Building Angular Services for Backend API Data
Step 1: Initialize Agular Application:
ng new app-name
Step 2: Create Angular Services:
ng generate service services/app-service
Step 3: Update AppConfig File:
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideClientHydration } from '@angular/platform-browser';
import { provideHttpClient, withFetch } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
provideClientHydration(),
provideHttpClient(withFetch()),
],
};
Step 4: Create a folder named "types" and add an interface for your fields:
import { Address } from './address';
export interface Employee {
id?: number;
name: string;
email: string;
contact: string;
addresses?: Address[];
}import { Employee } from './employee';
export interface Address {
id?: number;
city: string;
effectiveDate: string;
endDate?: string;
employee?: Employee;
}
Step 5: Write the service code to fetch data from the API:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Address } from '../types/address';
@Injectable({
providedIn: 'root',
})
export class AddressService {
private baseUrl = 'http://localhost:8088/api/addresses';
constructor(private http: HttpClient) {}
getAllAddresses(): Observable<Address[]> {
return this.http.get<Address[]>(this.baseUrl);
}
getAddressById(id: number): Observable<Address> {
return this.http.get<Address>(`${this.baseUrl}/${id}`);
}
createAddress(address: Address): Observable<Address> {
return this.http.post<Address>(this.baseUrl, address);
}
updateAddress(id: number, address: Address): Observable<Address> {
return this.http.put<Address>(`${this.baseUrl}/${id}`, address);
}
deleteAddress(id: number): Observable<void> {
return this.http.delete<void>(`${this.baseUrl}/${id}`);
}
isDuplicateAddress(city: string, employeeId: number): Observable<boolean> {
return this.http.get<boolean>(`${this.baseUrl}/duplicate`, {
params: { city, employeeId: employeeId.toString() },
});
}
getAddressByNameAndDate(
employeeName: string,
date: string
): Observable<Address[]> {
return this.http.get<Address[]>(
`${this.baseUrl}/employee/${employeeName}/date`,
{
params: { date },
}
);
}
}
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Employee } from '../types/employee';
import { Address } from '../types/address';
@Injectable({
providedIn: 'root',
})
export class EmployeeService {
private baseUrl = 'http://localhost:8088/api/employees'; // Replace with your backend URL
constructor(private http: HttpClient) {}
getAllEmployees(): Observable<Employee[]> {
return this.http.get<Employee[]>(this.baseUrl);
}
getEmployeeById(id: number): Observable<Employee> {
return this.http.get<Employee>(`${this.baseUrl}/${id}`);
}
createEmployee(employee: Employee): Observable<Employee> {
return this.http.post<Employee>(this.baseUrl, employee);
}
updateEmployee(id: number, employee: Employee): Observable<Employee> {
return this.http.put<Employee>(`${this.baseUrl}/${id}`, employee);
}
deleteEmployee(id: number): Observable<void> {
return this.http.delete<void>(`${this.baseUrl}/${id}`);
}
// Update employee addresses
updateEmployeeAddresses(
employeeId: number,
addresses: Address[]
): Observable<Address[]> {
const url = `${this.baseUrl}/${employeeId}/addresses`; // Assuming endpoint for updating addresses
return this.http.put<Address[]>(url, addresses);
}
}
Step 6: Create a components:
ng generate component components/emp/emp
ng generate component components/emp/emp-details
ng generate component components/emp/add-employee
ng generate component components/emp/add-address
ng generate component components/emp/edit-emp
Step 7: Create a Router in app.routes.ts
import { Routes } from '@angular/router';
import { HomeComponent } from './components/home/home.component';
import { HrViewComponent } from './components/hr/hr-view/hr-view.component';
import { HrEditComponent } from './components/hr/hr-edit/hr-edit.component';
import { EmpComponent } from './components/emp/emp/emp.component';
import { EmpDetailsComponent } from './components/emp/emp-details/emp-details.component';
import { EditEmpComponent } from './components/emp/edit-emp/edit-emp.component';
import { AddEmployeeComponent } from './components/emp/add-employee/add-employee.component';
import { AddAddressComponent } from './components/emp/add-address/add-address.component';
import { AddAddressEmpComponent } from './components/emp/add-address-emp/add-address-emp.component';
import { AddEmployeeAddressComponent } from './components/emp/add-employee-address/add-employee-address.component';
import { GetAddressComponent } from './components/emp/get-address/get-address.component';
export const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'emp', component: EmpComponent },
{ path: 'add-emp', component: AddEmployeeComponent },
{ path: 'add-employee-address', component: AddEmployeeAddressComponent },
{ path: 'add-employee-address/:id', component: AddEmployeeAddressComponent },
{ path: 'get-employee-address', component: GetAddressComponent },
{ path: 'emp/:id', component: EmpDetailsComponent },
{ path: 'edit-emp/:id', component: EditEmpComponent },
{ path: 'add-address/:id', component: AddAddressComponent },
{ path: 'add-address-emp/:id', component: AddAddressEmpComponent },
{ path: 'view/:id', component: HrViewComponent },
{ path: 'edit/:id', component: HrEditComponent },
];
Step 8: Code each component according to your requirements.
Here, I will provide some detailed solutions to help you understand how to fetch APIs in real-time.
Components: [HTML & TS File]
EmpComponent:
import { Component } from '@angular/core';
import { EmployeeService } from '../../../services/employee.service';
import { Employee } from '../../../types/employee';
import { RouterLink } from '@angular/router';
@Component({
selector: 'app-emp',
standalone: true,
imports: [RouterLink],
templateUrl: './emp.component.html',
styleUrl: './emp.component.css',
})
export class EmpComponent {
emp: Employee[] = [];
constructor(private empService: EmployeeService) {}
ngOnInit() {
this.getAllEmp();
}
getAllEmp() {
this.empService.getAllEmployees().subscribe((data) => {
this.emp = data;
});
}
}
<div class="px-10">
<div class="px-10">
<div class="flex flex-wrap gap-10 justify-start m-5 px-10">
@for (item of emp; track $index) {
<div class="bg-white rounded-lg shadow-md p-4 w-96">
<div class="flex justify-between mb-2">
<h2 class="text-xl font-bold">{{ item.name }}</h2>
</div>
<div class="text-sm mb-2 flex flex-col gap-y-2">
<p><strong>Email:</strong> {{ item.email }}</p>
<p><strong>Contact:</strong> {{ item.contact }}</p>
</div>
<div class="flex justify-start mt-5 mb-2">
<button
[routerLink]="'/emp/' + item.id"
class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
>
View
</button>
</div>
</div>
}
</div>
<div class="flex gap-x-10">
<div class="fixed bottom-5 right-5">
<button
[routerLink]="'/add-employee-address'"
class="bg-indigo-600 text-white px-4 py-3 rounded-full shadow-lg hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-opacity-50"
>
Add Employee
</button>
</div>
</div>
</div>
</div>
EmpDetailsComponent:
import { Component } from '@angular/core';
import { EmployeeService } from '../../../services/employee.service';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { Employee } from '../../../types/employee';
import { FormsModule } from '@angular/forms';
import { AddressService } from '../../../services/address.service';
import { AddressWithId } from '../../../types/add';
import { Location } from '@angular/common';
import { AddAddressComponent } from '../add-address/add-address.component';
@Component({
selector: 'app-emp-details',
standalone: true,
imports: [RouterLink, FormsModule, AddAddressComponent],
templateUrl: './emp-details.component.html',
styleUrl: './emp-details.component.css',
})
export class EmpDetailsComponent {
emp!: Employee;
editing = false;
addressForm = false;
showAddBatchForm: boolean = false;
employee: Employee = {
id: 0,
name: '',
email: '',
contact: '',
addresses: [],
};
constructor(
private empService: EmployeeService,
private activatedRouter: ActivatedRoute,
private router: Router,
private route: ActivatedRoute,
private addressService: AddressService,
private location: Location
) {}
ngOnInit() {
this.getEmployeeById();
const id = this.activatedRouter.snapshot.params['id'];
this.fetchEmployeeData(id);
}
fetchEmployeeData(id: number): void {
this.empService.getEmployeeById(id).subscribe((data: Employee) => {
this.employee = data;
});
}
submitForm(): void {
console.log(this.employee);
const id = Number(this.route.snapshot.paramMap.get('id'));
// Update employee details
this.empService.updateEmployee(id, this.employee).subscribe(
() => {
console.log('Employee details updated successfully');
this.getEmployeeById();
},
(error) => {
console.error('Error updating employee details:', error);
}
);
}
getEmployeeById() {
let id = this.activatedRouter.snapshot.params['id'];
this.empService.getEmployeeById(id).subscribe((data: Employee | null) => {
if (data) {
this.emp = data;
} else {
console.error('Employee data is null');
this.router.navigateByUrl('/emp');
}
});
}
deleteEmp() {
let id = this.activatedRouter.snapshot.params['id'];
this.empService.deleteEmployee(id).subscribe(() => {
console.log('Employee deleted successfully!');
this.router.navigateByUrl('/emp');
});
}
toggleEditing(): void {
this.editing = !this.editing;
}
addressFormShown(): void {
this.addressForm = !this.addressForm;
}
closeAddBatchForm() {
this.addressForm = false;
}
}
@if (emp) {
<div class="flex flex-wrap gap-4 justify-center items-center mt-14 m-5 px-10">
@if (!editing) {
<div class="bg-white rounded-lg shadow-md p-4 w-1/2">
<div class="flex justify-between mb-2">
<h2 class="text-xl font-bold">{{ emp.name }}</h2>
</div>
<div class="text-sm mb-2 flex flex-col gap-y-2">
<p><strong>Email:</strong> {{ emp.email }}</p>
<p><strong>Contact:</strong> {{ emp.contact }}</p>
</div>
<div
class="address-items overflow-x-auto max-h-72 rounded-sm custom-scrollbar"
>
<table class="table-auto w-full">
<thead>
<tr class="bg-gray-200">
<th class="px-4 py-2">City</th>
<th class="px-4 py-2">Effective Date</th>
<th class="px-4 py-2">End Date</th>
</tr>
</thead>
<tbody>
@for (address of emp.addresses; track $index) {
<tr class="text-center odd:bg-white even:bg-slate-200">
<td class="border px-4 py-2">
<span class="w-[80%]">{{ address.city }} </span>
</td>
<td class="border px-4 py-2">
<span class="w-[80%]">{{ address.effectiveDate }}</span>
</td>
<td class="border px-4 py-2">
<span class="w-[80%]">{{
address.endDate ? address.endDate : "Present"
}}</span>
</td>
</tr>
}
</tbody>
</table>
</div>
<!-- [routerLink]="'/edit-emp/' + emp.id" -->
<div class="flex gap-2 mt-5">
<button
(click)="toggleEditing()"
class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
>
Edit Details
</button>
<button
(click)="deleteEmp()"
class="bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600"
>
Delete
</button>
<button
[routerLink]="'/add-employee-address/' + emp.id"
class="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600"
>
Add Address
</button>
</div>
</div>
}
<!-- Form view -->
@if (editing) {
<div class="bg-white rounded-lg shadow-md p-4 w-1/2">
<form (ngSubmit)="submitForm()">
<div class="flex justify-between mb-2">
<input
type="text"
id="name"
name="name"
[(ngModel)]="employee.name"
class="text-xl font-bold block w-full focus:outline-none"
required
/>
</div>
<div class="text-sm mb-2 flex flex-col gap-y-2">
<p class="flex items-center justify-center">
<strong>Email:</strong>
<input
type="email"
id="email"
name="email"
[(ngModel)]="employee.email"
class="block w-full ml-1 focus:outline-none sm:text-sm"
required
/>
</p>
<p class="flex items-center justify-center">
<strong>Contact:</strong>
<input
type="text"
id="contact"
name="contact"
[(ngModel)]="employee.contact"
class="block w-full ml-1 focus:outline-none sm:text-sm"
required
/>
</p>
</div>
<div class="overflow-x-auto max-h-72">
<table class="table-auto w-full">
<thead>
<tr class="bg-gray-200">
<th class="px-4 py-2">City</th>
<th class="px-4 py-2">Effective Date</th>
<th class="px-4 py-2">End Date</th>
</tr>
</thead>
<tbody>
@for (address of emp.addresses; track $index) {
<tr class="text-center odd:bg-white even:bg-slate-200">
<td class="border px-4 py-2">
<span class="w-[80%]">{{ address.city }} </span>
</td>
<td class="border px-4 py-2">
<span class="w-[80%]">{{ address.effectiveDate }}</span>
</td>
<td class="border px-4 py-2">
<span class="w-[80%]">{{
address.endDate ? address.endDate : "Present"
}}</span>
</td>
</tr>
}
</tbody>
</table>
</div>
<div class="flex gap-2 mt-5">
<button
type="submit"
(click)="toggleEditing()"
class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
>
Save Details
</button>
<button
type="button"
(click)="toggleEditing()"
class="bg-gray-400 text-white px-4 py-2 rounded hover:bg-gray-600"
>
Cancel
</button>
</div>
</form>
</div>
}
</div>
} @if (addressForm) {
<div>
<app-add-address (formClosed)="closeAddBatchForm()"></app-add-address>
</div>
}
AddEmployeeComponent:
import { Component } from '@angular/core';
import { Employee } from '../../../types/employee';
import { EmployeeService } from '../../../services/employee.service';
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
@Component({
selector: 'app-add-employee',
standalone: true,
imports: [FormsModule],
templateUrl: './add-employee.component.html',
styleUrl: './add-employee.component.css',
})
export class AddEmployeeComponent {
employee: Employee = {
name: '',
email: '',
contact: '',
addresses: [],
};
address = {
city: '',
effectiveDate: new Date().toISOString(), // Setting current date
endDate: '', // Setting end date to null
};
constructor(
private employeeService: EmployeeService,
private router: Router
) {}
submitForm() {
this.employee.addresses = [this.address]; // Add the address to the employee
this.employeeService.createEmployee(this.employee).subscribe(
(response) => {
console.log('Employee created successfully!', response);
this.router.navigateByUrl('/emp');
},
(error) => {
console.error('Error creating employee:', error);
}
);
}
}
<div class="max-w-md mx-auto bg-white p-8 rounded-xl mt-20 shadow-lg space-y-4">
<h2 class="text-2xl font-bold text-gray-800 text-center">Employee</h2>
<form class="space-y-6" (ngSubmit)="submitForm()">
<div class="space-y-4">
<!-- Employee Name -->
<div>
<label for="name" class="block text-sm font-medium text-gray-700"
>Name</label
>
<input
type="text"
id="name"
name="name"
[(ngModel)]="employee.name"
class="mt-1 block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
required
/>
</div>
<!-- Employee Email -->
<div>
<label for="email" class="block text-sm font-medium text-gray-700"
>Email</label
>
<input
type="email"
id="email"
name="email"
[(ngModel)]="employee.email"
class="mt-1 block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
required
/>
</div>
<!-- Employee Contact -->
<div>
<label for="contact" class="block text-sm font-medium text-gray-700"
>Contact</label
>
<input
type="text"
id="contact"
name="contact"
[(ngModel)]="employee.contact"
class="mt-1 block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
required
/>
</div>
<!-- Employee Contact -->
<div>
<label for="contact" class="block text-sm font-medium text-gray-700"
>Address</label
>
<input
type="text"
id="city"
name="city"
[(ngModel)]="address.city"
class="mt-1 block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
required
/>
</div>
</div>
<!-- Submit Button -->
<div class="mt-6">
<button
type="submit"
class="w-full inline-flex items-center justify-center px-6 py-3 border border-transparent rounded-lg shadow-sm text-base font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition duration-300 ease-in-out transform hover:scale-105"
>
Submit
</button>
</div>
</form>
</div>
AddAddressComponent:
import { Component, EventEmitter, Output } from '@angular/core';
import { AddressService } from '../../../services/address.service';
import { Address } from '../../../types/address';
import { ActivatedRoute, Router } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { EmployeeService } from '../../../services/employee.service';
import { AddressWithId } from '../../../types/add';
@Component({
selector: 'app-add-address',
standalone: true,
imports: [FormsModule],
templateUrl: './add-address.component.html',
styleUrl: './add-address.component.css',
})
export class AddAddressComponent {
@Output() formClosed = new EventEmitter<void>();
address: AddressWithId = {
city: '',
effectiveDate: new Date().toISOString(),
endDate: '',
employeeId: 0,
};
constructor(
private addressService: AddressService,
private router: Router,
private route: ActivatedRoute,
private empService: EmployeeService
) {}
closeForm() {
this.formClosed.emit();
}
ngOnInit(): void {
let id = this.route.snapshot.params['id'];
this.address.employeeId = id;
}
onSubmit() {
this.addressService.createAddress(this.address).subscribe(
(response) => {
let id = this.route.snapshot.params['id'];
console.log('Employee created successfully!', response);
this.router.navigateByUrl('/emp/' + id);
},
(error) => {
console.error('Error creating employee:', error);
}
);
}
}
<!-- class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50" -->
<div
class="fixed inset-0 flex items-center justify-center"
(click)="closeForm()"
>
<div
class="w-[500px] mx-auto p-6 bg-white rounded-lg shadow-md"
(click)="$event.stopPropagation()"
>
<button
(click)="closeForm()"
class="absolute top-0 right-0 mt-4 mr-4 text-gray-600 hover:text-gray-900"
>
×
</button>
<h2 class="text-2xl font-bold mb-4">Add Address</h2>
<form (ngSubmit)="onSubmit()">
<div class="mb-4">
<label for="city" class="block text-sm font-medium text-gray-700"
>City</label
>
<input
id="city"
name="city"
type="text"
[(ngModel)]="address.city"
class="mt-1 block w-full p-3 border border-b rounded-md shadow-sm hover:focus:border-indigo-500 hover:focus:ring-indigo-500 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
/>
</div>
<!-- <div class="mb-4">
<label for="effectiveDate" class="block text-sm font-medium text-gray-700"
>Effective Date</label
>
<input
id="effectiveDate"
name="effectiveDate"
type="date"
[(ngModel)]="address.effectiveDate"
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
/>
</div>
<div class="mb-4">
<label for="endDate" class="block text-sm font-medium text-gray-700"
>End Date</label
>
<input
id="endDate"
name="endDate"
type="date"
[(ngModel)]="address.endDate"
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
/>
</div> -->
<!-- <div class="mb-4">
<label for="employeeId" class="block text-sm font-medium text-gray-700">Employee ID</label>
<input
id="employeeId"
type="number"
formControlName="employeeId"
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
/>
@if (addressForm.get('employeeId')?.invalid && addressForm.get('employeeId')?.touched) {
<div *ngIf="addressForm.get('employeeId')?.invalid && addressForm.get('employeeId')?.touched" class="text-red-500 text-sm">
Employee ID is required
</div>
}
</div> -->
<div class="flex justify-end">
<button
type="submit"
class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-opacity-50"
>
Add Address
</button>
</div>
</form>
</div>
</div>
EditEmployeeComponent:
import { Component } from '@angular/core';
import { Employee } from '../../../types/employee';
import { EmployeeService } from '../../../services/employee.service';
import { ActivatedRoute, Router } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { AddressService } from '../../../services/address.service';
@Component({
selector: 'app-edit-emp',
standalone: true,
imports: [FormsModule],
templateUrl: './edit-emp.component.html',
styleUrl: './edit-emp.component.css',
})
export class EditEmpComponent {
employee: Employee = {
id: 0,
name: '',
email: '',
contact: '',
addresses: [],
};
constructor(
private empService: EmployeeService,
private route: ActivatedRoute,
private router: Router,
private addressService: AddressService
) {}
ngOnInit(): void {
const id = Number(this.route.snapshot.paramMap.get('id'));
this.fetchEmployeeData(id);
}
fetchEmployeeData(id: number): void {
this.empService.getEmployeeById(id).subscribe((data: Employee) => {
this.employee = data;
// Ensure addresses is initialized
if (!this.employee.addresses) {
this.employee.addresses = [];
}
});
}
submitForm(): void {
console.log(this.employee);
const id = Number(this.route.snapshot.paramMap.get('id'));
// Update employee details
this.empService.updateEmployee(id, this.employee).subscribe(
() => {
console.log('Employee details updated successfully');
this.router.navigateByUrl('/emp');
},
(error) => {
console.error('Error updating employee details:', error);
}
);
}
}
<div
class="container mx-auto w-full flex flex-col items-center justify-center h-screen"
>
<h1 class="text-2xl font-bold mb-4">Edit Employee Details</h1>
<form (ngSubmit)="submitForm()" class="max-w-lg">
<div class="mb-4">
<label for="name" class="block text-sm font-medium text-gray-700"
>Name</label
>
<input
type="text"
id="name"
name="name"
[(ngModel)]="employee.name"
class="mt-1 block w-full px-3 py-2 border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
required
/>
</div>
<div class="mb-4">
<label for="email" class="block text-sm font-medium text-gray-700"
>Email</label
>
<input
type="email"
id="email"
name="email"
[(ngModel)]="employee.email"
class="mt-1 block w-full px-3 py-2 border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
required
/>
</div>
<div class="mb-4">
<label for="contact" class="block text-sm font-medium text-gray-700"
>Contact</label
>
<input
type="text"
id="contact"
name="contact"
[(ngModel)]="employee.contact"
class="mt-1 block w-full px-3 py-2 border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
required
/>
</div>
<!-- Address Section -->
<div class="mb-4">
<h2 class="text-lg font-semibold mb-2">Addresses</h2>
<table class="table-auto w-full">
<thead>
<tr class="bg-gray-200">
<th class="px-4 py-2">City</th>
<th class="px-4 py-2">Effective Date</th>
<th class="px-4 py-2">End Date</th>
</tr>
</thead>
<tbody>
@for (address of employee.addresses; track address) {
<tr class="bg-white">
<td class="border px-4 py-2">
<input
type="text"
name="city{{ address.city }}"
[(ngModel)]="address.city"
class="border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</td>
<td class="border px-4 py-2">
<input
type="text"
name="effectiveDate{{ address.effectiveDate }}"
[(ngModel)]="address.effectiveDate"
class="border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</td>
<td class="border px-4 py-2">
<input
type="text"
name="endDate{{ address.endDate }}"
[(ngModel)]="address.endDate"
class="border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</td>
</tr>
}
</tbody>
</table>
</div>
<button
type="submit"
class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
>
Save Changes
</button>
</form>
</div>
GetAddressComponent:
import { Component } from '@angular/core';
import { Address } from '../../../types/address';
import { AddressService } from '../../../services/address.service';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-get-address',
standalone: true,
imports: [FormsModule, CommonModule],
templateUrl: './get-address.component.html',
styleUrl: './get-address.component.css',
})
export class GetAddressComponent {
addresses: Address[] = [];
employeeName: string = '';
date: string = '';
errorMessage: string = '';
loading: boolean = false;
constructor(private addressService: AddressService) {}
ngOnInit(): void {}
getAddressByNameAndDate(): void {
const selectedDate = new Date(this.date);
const today = new Date();
if (!this.employeeName) {
this.errorMessage = '*The name field cannot be empty.';
this.addresses = [];
return;
}
if (!this.date) {
this.errorMessage = '*The date field cannot be empty.';
this.addresses = [];
return;
}
if (selectedDate > today) {
this.errorMessage = '*The selected date cannot be in the future.';
this.addresses = [];
return;
}
if (this.employeeName && this.date) {
this.loading = true;
this.addressService
.getAddressByNameAndDate(this.employeeName, this.date)
.subscribe(
(addresses: Address[]) => {
this.addresses = addresses;
this.errorMessage = '';
this.loading = false;
},
(error) => {
this.errorMessage = 'An error occurred while fetching addresses.';
this.addresses = [];
this.loading = false;
}
);
}
}
submitForm() {}
}
<div class="max-w-md mx-auto bg-white p-8 rounded-xl mt-20 shadow-lg space-y-4">
<h2 class="text-2xl font-bold text-gray-800 text-center">
Find Your Address
</h2>
<div class="space-y-4">
<!-- Employee Name -->
<div>
<label for="name" class="block text-sm font-medium text-gray-700"
>Name</label
>
<input
type="text"
id="name"
name="name"
[(ngModel)]="employeeName"
class="mt-1 block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
required
/>
</div>
<!-- [(ngModel)]="employee.name" -->
<!-- Employee Contact -->
<div>
<label for="contact" class="block text-sm font-medium text-gray-700"
>Pick Date</label
>
<input
type="date"
id="date"
name="date"
[(ngModel)]="date"
class="mt-1 block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
required
/>
</div>
@if (errorMessage) {
<div class="text-red-500 text-sm">{{ errorMessage }}</div>
}
<!-- [(ngModel)]="address.city" -->
</div>
<!-- Submit Button -->
<!-- type="submit" -->
<div class="mt-6">
<button
(click)="getAddressByNameAndDate()"
class="w-full inline-flex items-center justify-center px-6 py-3 border border-transparent rounded-lg shadow-sm text-base font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition duration-300 ease-in-out transform hover:scale-105"
>
Get Address
</button>
</div>
@if (addresses.length) {
<div>
<h3><strong>Address:</strong></h3>
<ul class="flex items-center justify-between">
@for (address of addresses; track $index) {
<li>
<strong> {{ address.city }} </strong>
</li>
<img src="/icons/map.png" alt="map image" height="50" width="50" />
}
</ul>
</div>
}@else if (loading) {
<div class="flex justify-center mt-6">
<div class="loader"></div>
</div>
}
</div>
Subscribe to my newsletter
Read articles from Vivekanand Mendhe directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Vivekanand Mendhe
Vivekanand Mendhe
Hey..!