Saturday, July 4, 2026

Custom Components, Directives, and Pipes in Angular – Complete Guide with Real-Time Examples

 Angular applications are built using three fundamental building blocks:

  1. Components – Build reusable UI sections.

  2. Directives – Add or modify the behavior of HTML elements.

  3. Pipes – Transform data for display without changing the original value.

A real-world Employee Management System uses all three together.

Employee Management Application

           Angular
               │
    ┌──────────┼──────────┐
    │          │          │
Components  Directives   Pipes
    │          │          │
Employee    Highlight    Currency
Dashboard   Permission   Date
Login       Validation   Custom Format

1. Custom Components

What is a Component?

A component is a reusable UI element that contains:

  • HTML (Template)

  • CSS (Styles)

  • TypeScript (Logic)

Every screen in Angular is made up of components.


Real-Time Banking Example

Consider an Online Banking Application.

Internet Banking

-----------------------------------------
Header Component
-----------------------------------------
Menu Component
-----------------------------------------
Account Summary Component
-----------------------------------------
Transaction Component
-----------------------------------------
Footer Component
-----------------------------------------

Instead of writing one huge page, each section becomes a reusable component.


Create Component

ng generate component employee

or

ng g c employee

Employee Component

employee.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-employee',
  templateUrl: './employee.component.html'
})
export class EmployeeComponent {

  employeeName = "Mahesh";
  designation = "Software Engineer";

}

employee.component.html

<h2>{{employeeName}}</h2>

<p>{{designation}}</p>

App Component

<app-employee></app-employee>

Output

Mahesh

Software Engineer

Real-Time Example

Employee Dashboard

Dashboard

↓

Employee Component

↓

Employee Details

↓

Salary Component

↓

Leave Component

↓

Attendance Component

Each is a separate component.


Parent to Child Communication

Parent Component

<app-employee
[employeeName]="name">
</app-employee>

Child Component

@Input()
employeeName:string="";

Output

Mahesh

Child to Parent Communication

Child

@Output()
save=new EventEmitter();

SaveEmployee(){

this.save.emit();

}

Parent

<app-employee
(save)="SaveCompleted()">
</app-employee>

Real-Time Example

Employee Form

Employee Component

↓

Click Save

↓

EventEmitter

↓

Parent Dashboard Refreshes

Benefits of Components

  • Reusable

  • Easy to Maintain

  • Independent

  • Testable

  • Modular


2. Custom Directives

What is a Directive?

Directives change the appearance or behavior of HTML elements.

Angular has three types of directives:

  • Component Directives

  • Structural Directives

  • Attribute Directives


Structural Directives

These change the DOM structure.

Examples

*ngIf

*ngFor

*ngSwitch

Example

<div *ngIf="isAdmin">

Admin Panel

</div>

Attribute Directives

Change appearance.

Example

ngStyle

ngClass
<div
[ngStyle]="{'color':'red'}">
Employee
</div>

Custom Attribute Directive

Suppose HR wants employees with low performance highlighted in red.

Create Directive

ng generate directive highlight

highlight.directive.ts

import {
 Directive,
 ElementRef,
 HostListener
} from '@angular/core';

@Directive({
 selector:'[appHighlight]'
})
export class HighlightDirective{

 constructor(private element:ElementRef){}

 @HostListener('mouseenter')

 onMouseEnter(){

 this.element.nativeElement.style.backgroundColor="yellow";

 }

 @HostListener('mouseleave')

 onMouseLeave(){

 this.element.nativeElement.style.backgroundColor="white";

 }

}

Use Directive

<p appHighlight>

Employee Name

</p>

Output

Mouse Hover

↓

Yellow Background

Mouse Leave

↓

White Background

Real-Time Banking Example

Low Balance

↓

Highlight Red

High Balance

↓

Highlight Green

Permission Directive Example

Only Managers can view salary.

<div *appHasRole="'Manager'">

Salary Details

</div>

Custom Directive

@Input()
appHasRole:string="";

Real-Time

Employee Login

↓

Role = Employee

↓

Salary Hidden

Manager

Role = Manager

↓

Salary Visible

Benefits of Directives

  • Reusable Behavior

  • Clean HTML

  • Better Readability

  • Centralized UI Logic


3. Custom Pipes

What is a Pipe?

Pipes transform data before displaying it.

Original data remains unchanged.

Example

Mahesh

↓

MAHESH

Built-in Pipes

uppercase

lowercase

date

currency

json

slice

percent

titlecase

Example

{{salary | currency}}

Output

₹45,000.00

Custom Pipe

Suppose HR wants Employee IDs displayed with prefix.

101

↓

EMP-101

Generate Pipe

ng generate pipe employeeid

employeeid.pipe.ts

import {
 Pipe,
 PipeTransform
} from '@angular/core';

@Pipe({
 name:'employeeid'
})

export class EmployeeidPipe
implements PipeTransform{

 transform(value:number){

 return "EMP-"+value;

 }

}

Use Pipe

{{101 | employeeid}}

Output

EMP-101

Banking Example

Original

10001

Display

ACC-10001

Pipe

return "ACC-"+value;

Mask Account Number Pipe

Original

1234567890123456

Display

************3456

Pipe

transform(value:string){

return "************"+
value.slice(-4);

}

HTML

{{accountNumber | accountmask}}

Output

************3456

Real-Time Employee Example

Employee Object

employee={

id:101,

name:"Mahesh",

salary:75000,

joiningDate:new Date()

}

HTML

ID

{{employee.id | employeeid}}

<br>

Name

{{employee.name | uppercase}}

<br>

Salary

{{employee.salary | currency:'INR'}}

<br>

Joining

{{employee.joiningDate | date:'dd/MM/yyyy'}}

Output

ID : EMP-101

Name : MAHESH

Salary : ₹75,000

Joining : 15/03/2025

Complete Real-Time Architecture

Employee Portal

                 Angular
                    │
    ┌───────────────┼────────────────┐
    │               │                │
Component       Directive          Pipe
    │               │                │
Employee      Highlight          Currency
Login         Permission         Date
Dashboard     Validation         Employee ID
Attendance    Tooltip            Account Mask
Leave         Hover Effect       Uppercase

Components vs Directives vs Pipes

FeatureComponentDirectivePipe
PurposeBuild UIModify behavior or appearanceTransform displayed data
Has HTML TemplateYesNoNo
ReusableYesYesYes
Used InScreens and UI sectionsHTML elementsData binding expressions
ExampleEmployee ListHighlight invalid fieldsCurrency, Date, Masking

Real-Time Project Example (Employee Management)

RequirementAngular FeatureExample
Employee DashboardComponent<app-dashboard>
Employee DetailsComponent<app-employee-details>
Highlight overdue tasksDirectiveappHighlight
Restrict manager-only contentDirectiveappHasRole
Format Employee IDPipeemployeeid
Display SalaryBuilt-in Pipecurrency
Format Joining DateBuilt-in Pipedate
Mask Aadhaar/Account NumberCustom Pipeaccountmask

Common Interview Questions

1. What is the difference between a Component and a Directive?

Answer: A component has its own template, styles, and logic to create a part of the UI. A directive does not have its own view; it only changes the behavior or appearance of existing DOM elements.

2. When should you create a custom directive?

Answer: When the same UI behavior (such as role-based visibility, hover effects, validation styling, or highlighting) is needed across multiple components.

3. When should you create a custom pipe?

Answer: When the same data formatting logic (such as masking account numbers, formatting employee IDs, or custom text transformations) is reused in multiple templates.

4. Are pipes suitable for heavy business logic?

Answer: No. Pipes should only be used for presentation logic. Complex business logic belongs in services or components.

5. How do Components, Directives, and Pipes work together?

Answer: Components build the UI, directives add reusable behavior to elements, and pipes format the displayed data, resulting in clean, maintainable, and reusable Angular applications.

Angular Lifecycle Hooks – Complete Guide with Real-Time Examples (Angular 16/17/18+)

 Angular Lifecycle Hooks are special methods that Angular automatically calls during the lifecycle of a component.

Think of a component like a person.

  • Born → Constructor

  • Gets Data → ngOnInit

  • Receives Updates → ngOnChanges

  • Checks Changes → ngDoCheck

  • Displays Content → ngAfterViewInit

  • Destroyed → ngOnDestroy


Angular Component Lifecycle

Constructor
      │
      ▼
ngOnChanges
      │
      ▼
ngOnInit
      │
      ▼
ngDoCheck
      │
      ▼
ngAfterContentInit
      │
      ▼
ngAfterContentChecked
      │
      ▼
ngAfterViewInit
      │
      ▼
ngAfterViewChecked
      │
      ▼
ngOnDestroy

1. Constructor

Purpose

The constructor is the first method executed when Angular creates a component.

Used for:

  • Dependency Injection

  • Initializing services

  • Basic variable initialization

Example

constructor(private employeeService: EmployeeService) {
    console.log("Constructor Called");
}

Output

Constructor Called

Real-Time Example

Imagine opening Amazon.

When the page loads,

Angular creates ProductComponent.

Before displaying products,

Angular injects

  • ProductService

  • CartService

  • LoggerService

using Constructor.

Amazon Page

↓

Constructor

↓

Inject Services

↓

Load Component

2. ngOnChanges()

Purpose

Called whenever an Input property changes.

Only works with @Input().

Example

Parent Component

<app-child [employee]="employee"></app-child>

Child Component

@Input() employee:any;

ngOnChanges(changes: SimpleChanges){
   console.log(changes);
}

Output

Employee Changed

Real-Time Example

Employee Portal

Manager selects another employee.

Employee 101

↓

Employee 205

↓

Child Component Updated

↓

ngOnChanges()

Perfect example

Employee Details Screen


3. ngOnInit()

Purpose

Runs only once after Angular initializes the component.

Most commonly used hook.

Used for

  • API Calls

  • Loading data

  • Initial calculations

Example

ngOnInit(){

   this.loadEmployees();

}
GET /api/employees

Real-Time Banking Example

Customer Dashboard

After login

Angular calls

GET Account Details

GET Transactions

GET Loans

inside

ngOnInit()

4. ngDoCheck()

Purpose

Custom change detection.

Angular calls this hook during every change detection cycle.

Example

ngDoCheck(){

   console.log("Checking Changes");

}

Real-Time Example

Shopping Cart

User changes

  • Quantity

  • Price

  • Coupon

Angular continuously checks

Subtotal

GST

Discount

Final Amount

using ngDoCheck()


5. ngAfterContentInit()

Purpose

Runs once after external content is projected using

<ng-content>

Example

<app-card>

   <h2>Employee Information</h2>

</app-card>

Card Component

<div class="card">

<ng-content></ng-content>

</div>
ngAfterContentInit(){

console.log("Content Loaded");

}

Real-Time Example

Dashboard Card

Employee Name

Employee Salary

Employee Department

are projected into Card Component.

Angular executes

ngAfterContentInit()

6. ngAfterContentChecked()

Runs after every content check.

Example

ngAfterContentChecked(){

console.log("Content Checked");

}

Real-Time Example

Employee Dashboard

Manager changes employee role.

Projected content updates.

Angular verifies projected content.


7. ngAfterViewInit()

Purpose

Runs after the component view is fully initialized.

Most commonly used for

  • ViewChild

  • Charts

  • Google Maps

  • DataTables

Example

@ViewChild('txtName')
name!:ElementRef;

ngAfterViewInit(){

this.name.nativeElement.focus();

}

Real-Time Example

Login Page

Cursor automatically focuses on

Username textbox.

Username

Password

Angular waits until UI is created.

Then

Focus()

inside

ngAfterViewInit()

8. ngAfterViewChecked()

Runs every time Angular checks component view.

Example

ngAfterViewChecked(){

console.log("View Checked");

}

Real-Time Example

Dashboard

Charts

Tables

Graphs

Whenever data changes,

Angular checks the whole view.


9. ngOnDestroy()

Purpose

Called before Angular destroys the component.

Used for cleanup.

Very important.

Used for

  • Unsubscribe Observable

  • Clear Timer

  • Remove Event Listener

  • Close SignalR Connection

  • Close WebSocket

Example

subscription!:Subscription;

ngOnInit(){

this.subscription=this.employeeService.getEmployees()
.subscribe();

}

ngOnDestroy(){

this.subscription.unsubscribe();

}

Real-Time Banking Example

Customer Dashboard

User logs out.

Angular

Disconnect SignalR

Stop Timer

Unsubscribe API

Remove Events

Destroy Component

Complete Real-Time Employee Management Example

Employee List

constructor()

↓

Inject EmployeeService

↓

ngOnInit()

↓

Call Employee API

↓

Display Employees

↓

Manager selects employee

↓

ngOnChanges()

↓

Employee Details Updated

↓

User edits salary

↓

ngDoCheck()

↓

Salary recalculated

↓

Dashboard Card Loaded

↓

ngAfterContentInit()

↓

Chart Loaded

↓

ngAfterViewInit()

↓

User navigates away

↓

ngOnDestroy()

↓

Unsubscribe APIs

Complete Sample Component

import {
 Component,
 OnInit,
 OnChanges,
 DoCheck,
 AfterContentInit,
 AfterContentChecked,
 AfterViewInit,
 AfterViewChecked,
 OnDestroy,
 Input,
 SimpleChanges
} from '@angular/core';

@Component({
 selector:'app-employee',
 templateUrl:'employee.component.html'
})
export class EmployeeComponent
implements
OnInit,
OnChanges,
DoCheck,
AfterContentInit,
AfterContentChecked,
AfterViewInit,
AfterViewChecked,
OnDestroy{

 @Input() employee:any;

 constructor(){
   console.log("Constructor");
 }

 ngOnChanges(changes:SimpleChanges){
   console.log("ngOnChanges");
 }

 ngOnInit(){
   console.log("ngOnInit");
 }

 ngDoCheck(){
   console.log("ngDoCheck");
 }

 ngAfterContentInit(){
   console.log("ngAfterContentInit");
 }

 ngAfterContentChecked(){
   console.log("ngAfterContentChecked");
 }

 ngAfterViewInit(){
   console.log("ngAfterViewInit");
 }

 ngAfterViewChecked(){
   console.log("ngAfterViewChecked");
 }

 ngOnDestroy(){
   console.log("ngOnDestroy");
 }

}

Execution Order (First Time)

OrderLifecycle HookPurpose
1ConstructorCreate component and inject dependencies
2ngOnChangesDetect initial @Input() values
3ngOnInitInitialize component and load data
4ngDoCheckPerform custom change detection
5ngAfterContentInitInitialize projected content (<ng-content>)
6ngAfterContentCheckedCheck projected content
7ngAfterViewInitInitialize component view and child views
8ngAfterViewCheckedCheck the component view
9ngOnDestroyClean up resources before destruction

Which Hook to Use?

ScenarioRecommended Hook
Inject servicesconstructor()
Load API datangOnInit()
Detect @Input() changesngOnChanges()
Custom change detectionngDoCheck()
Work with projected contentngAfterContentInit()
Access @ViewChild or initialize UI librariesngAfterViewInit()
Subscribe to observablesngOnInit()
Unsubscribe, clear timers, close connectionsngOnDestroy()

Common Interview Questions

1. What is the difference between constructor() and ngOnInit()?

ConstructorngOnInit
JavaScript/TypeScript featureAngular lifecycle hook
Used for dependency injectionUsed for component initialization
Runs before Angular initializes the componentRuns after Angular has initialized inputs
Avoid API calls hereIdeal place for API calls

2. Which hook is best for calling APIs?

Answer: ngOnInit().

3. Which hook is used for cleanup?

Answer: ngOnDestroy().

4. Which hook is used with @ViewChild?

Answer: ngAfterViewInit().

5. Which hook is called when an @Input() value changes?

Answer: ngOnChanges().

6. Which lifecycle hook is called only once after component initialization?

Answer: ngOnInit().

7. Why is ngOnDestroy() important?

Answer: It prevents memory leaks by unsubscribing from observables, clearing timers, removing event listeners, and closing WebSocket or SignalR connections.


Best Practices

  • Use constructor() only for dependency injection and simple initialization.

  • Place API calls and business initialization logic in ngOnInit().

  • Keep ngDoCheck() lightweight because it runs frequently.

  • Use ngAfterViewInit() when interacting with the DOM or @ViewChild.

  • Always clean up subscriptions and resources in ngOnDestroy().

  • Avoid performing expensive operations inside ngAfterViewChecked() and ngAfterContentChecked() since they are called often.

This lifecycle knowledge is frequently tested in Angular interviews and is essential for building efficient, maintainable Angular applications.

Don't Copy

Protected by Copyscape Online Plagiarism Checker