Mastering Angular: A Complete Guide to Modern Web Development

479 0 0 0 0

Chapter 3: Directives and Pipes in Angular

Angular provides a rich set of tools for building dynamic, responsive, and maintainable front-end applications. Two of the most powerful tools in Angular are Directives and Pipes. These enable developers to manipulate the DOM and transform data directly in the template.


1. Understanding Angular Directives

Directives are classes that add behavior to elements in Angular applications. There are three types:

Directive Type

Description

Component Directives

A directive with a template. Every component is essentially a directive.

Structural Directives

Change the DOM layout by adding/removing elements (*ngIf, *ngFor).

Attribute Directives

Change the appearance or behavior of an element (ngClass, ngStyle).


1.1 Structural Directives

Structural directives affect layout by adding or removing elements. Common examples:

a) *ngIf

html

 

<p *ngIf="isLoggedIn">Welcome back, user!</p>

This renders the paragraph only if isLoggedIn is true.

b) *ngFor

html

 

<ul>

  <li *ngFor="let item of items">{{ item }}</li>

</ul>

Iterates over an array and renders a list item for each.

c) *ngSwitch

html

 

<div [ngSwitch]="status">

  <p *ngSwitchCase="'online'">Online</p>

  <p *ngSwitchCase="'offline'">Offline</p>

  <p *ngSwitchDefault>Unknown</p>

</div>


1.2 Attribute Directives

These modify the appearance or behavior of an element.

a) ngClass

html

 

<p [ngClass]="{ 'highlight': isImportant }">Conditional class</p>

b) ngStyle

html

 

<p [ngStyle]="{ 'color': isImportant ? 'red' : 'black' }">Styled text</p>


1.3 Creating a Custom Attribute Directive

bash

 

ng generate directive highlight

highlight.directive.ts:

ts

 

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

 

@Directive({

  selector: '[appHighlight]'

})

export class HighlightDirective {

  constructor(private el: ElementRef) {}

 

  @HostListener('mouseenter') onMouseEnter() {

    this.highlight('yellow');

  }

 

  @HostListener('mouseleave') onMouseLeave() {

    this.highlight('');

  }

 

  private highlight(color: string) {

    this.el.nativeElement.style.backgroundColor = color;

  }

}

Use it in a component:

html

 

<p appHighlight>Hover over me!</p>


2. Angular Pipes

Pipes transform data in the template. They are declared with the pipe | symbol.


2.1 Built-in Pipes

Pipe Name

Example

Description

date

`{{ today

date:'short' }}`

uppercase

`{{ name

uppercase }}`

lowercase

`{{ name

lowercase }}`

currency

`{{ price

currency }}`

percent

`{{ decimal

percent }}`

json

`{{ object

json }}`

slice

`{{ list

slice:1:4 }}`

titlecase

`{{ title

titlecase }}`


Example: Using date and currency

html

 

<p>Today is {{ today | date:'fullDate' }}</p>

<p>Price: {{ price | currency:'USD':true }}</p>


2.2 Chaining Pipes

You can use multiple pipes together:

html

 

<p>{{ user.name | uppercase | slice:0:5 }}</p>


2.3 Parameters in Pipes

Most pipes accept optional parameters.

html

 

<p>{{ total | currency:'EUR':'symbol':'1.2-2' }}</p>


3. Custom Pipes

Custom pipes allow you to encapsulate logic for data transformation.


3.1 Creating a Custom Pipe

bash

 

ng generate pipe truncate

truncate.pipe.ts:

ts

 

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

 

@Pipe({

  name: 'truncate'

})

export class TruncatePipe implements PipeTransform {

  transform(value: string, limit = 20, completeWords = false, ellipsis = '...'): string {

    if (!value) return '';

    if (completeWords) {

      limit = value.substr(0, limit).lastIndexOf(' ');

    }

    return value.length > limit ? value.substr(0, limit) + ellipsis : value;

  }

}

Use in a template:

html

 

<p>{{ longText | truncate:25:true }}</p>


4. Directives vs Pipes: Key Differences

Feature

Directives

Pipes

Purpose

Manipulate DOM elements

Transform data

Syntax

Applied as attributes [directive]

Applied with `{{ value

Output Type

HTML behavior

String, number, or transformed data

Types

Structural, Attribute, Component

Pure, Impure

Customizable

Yes

Yes


5. Built-in Structural Directive Best Practices

  1. Avoid nesting too many *ngIf and *ngFor – split logic into components.
  2. Use trackBy with *ngFor for better performance.

html

 

<li *ngFor="let item of items; trackBy: trackByFn">{{ item.name }}</li>

ts

 

trackByFn(index: number, item: any): number {

  return item.id;

}


6. Creating a Custom Structural Directive

bash

 

ng generate directive unless

unless.directive.ts:

ts

 

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

 

@Directive({

  selector: '[appUnless]'

})

export class UnlessDirective {

  constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) {}

 

  @Input() set appUnless(condition: boolean) {

    if (!condition) {

      this.viewContainer.createEmbeddedView(this.templateRef);

    } else {

      this.viewContainer.clear();

    }

  }

}

Use in HTML:

html

 

<p *appUnless="isLoggedIn">Please log in to continue.</p>


7. Pure vs Impure Pipes

Type

When to Use

Recalculates on

Pure

Data is immutable

Input change

Impure

Data is frequently changing

Every change detection

Default pipes are pure. For impure pipes:

ts

 

@Pipe({

  name: 'myPipe',

  pure: false

})


8. Combining Pipes and Directives

You can use pipes inside structural directives:

html

 

<li *ngFor="let name of names | slice:0:5">

  {{ name | titlecase }}

</li>


9. Testing Custom Pipes and Directives

Test cases ensure your custom logic behaves as expected.

Pipe Test Example

ts

 

it('should truncate text', () => {

  const pipe = new TruncatePipe();

  expect(pipe.transform('Angular is awesome', 7)).toBe('Angular...');

});

Directive Test Example

ts

 

it('should create an element when condition is false', () => {

  const directive = new UnlessDirective(templateRef, viewContainerRef);

  directive.appUnless = false;

  // expectations

});


10. Summary Table: Common Use Cases

Use Case

Directive or Pipe

Example

Hide element if not logged in

Directive

<p *ngIf="!isLoggedIn">Login</p>

Display a formatted price

Pipe

`{{ price

Iterate over product list

Directive

<li *ngFor="let p of products">

Show only part of a sentence

Pipe

`{{ sentence

Highlight on hover

Custom Directive

<div appHighlight>Hover me</div>

Truncate long string

Custom Pipe

`{{ text



Back

FAQs


1. Q: Is Angular suitable for beginners?

A: Yes, but having a basic understanding of TypeScript and JavaScript ES6 will help a lot.

2. Q: What language is Angular written in?

A: Angular uses TypeScript, which is a superset of JavaScript.

3. Q: What's the difference between AngularJS and Angular?

A: AngularJS (1.x) is the older version using JavaScript, while Angular (2+) uses TypeScript and a component-based architecture.

4. Q: Can I use Angular for mobile apps?

A: Yes, with frameworks like Ionic or NativeScript.

5. Q: How does Angular compare to React?

A: Angular is a full framework with built-in tools, while React is a library focused on UI.

6. Q: Is Angular good for large-scale applications?

A: Yes, Angular excels in large, structured, maintainable apps.

7. Q: What is Angular CLI?

A: It’s a command-line tool that helps scaffold, develop, and manage Angular applications efficiently.

8. Q: Do I need Node.js to use Angular?

A: Yes, Node.js is required to install Angular CLI and manage dependencies.

9. Q: What is a component in Angular?

A: A reusable unit of UI that consists of a template, logic, and styling.

10. Q: Can Angular be used with backend frameworks like Django or Laravel?

A: Yes, Angular can be paired with any backend via APIs.