DEV Community

Cover image for Angular Directives and Pipes: Complete Guide | Custom Directives, Pipes & Transformations
Md. Maruf Rahman
Md. Maruf Rahman

Posted on • Edited on • Originally published at practicaldev.online

Angular Directives and Pipes: Complete Guide | Custom Directives, Pipes & Transformations

When I first started with Angular, I thought directives and pipes were just nice-to-have features. Then I found myself writing the same conditional rendering logic in multiple components, and the same data transformation code in multiple templates. That's when I realized that custom directives and pipes are powerful tools for creating reusable, maintainable code.

Directives extend HTML with custom behavior. Structural directives (like *ngIf and *ngFor) change the DOM structure, while attribute directives (like [ngClass] and [ngStyle]) modify element appearance or behavior. Pipes transform data for display in templates—formatting dates, currencies, and text. Both are essential for building clean, maintainable Angular templates.

What are Angular Directives and Pipes?

Angular Directives provide:

  • Structural Directives - Change DOM structure (*ngIf, *ngFor, *ngSwitch)
  • Attribute Directives - Modify element appearance/behavior ([ngClass], [ngStyle])
  • Custom Directives - Reusable behavior for specific use cases

Angular Pipes provide:

  • Built-in Pipes - Date, currency, uppercase, lowercase, json, etc.
  • Custom Pipes - Data transformations specific to your application
  • Async Pipe - Handle Observables and Promises automatically

Built-in Structural Directives

Angular provides powerful structural directives out of the box:

<!-- *ngIf - Conditional rendering -->
<div *ngIf="isAuthenticated">
  <p>Welcome, user!</p>
</div>

<!-- *ngFor - Loop through arrays -->
<ul>
  <li *ngFor="let business of businesses; trackBy: trackByBusinessId">
    {{ business.name }}
  </li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Custom Structural Directive

Create custom structural directives for reusable conditional rendering:

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

@Directive({
  selector: '[appHasPermission]'
})
export class HasPermissionDirective {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
    private authService: AuthService
  ) {}

  @Input() set appHasPermission(permission: string) {
    const hasPermission = this.authService.hasPermission(permission);

    if (hasPermission) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
      this.viewContainer.clear();
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Built-in Pipes

Angular provides many built-in pipes for common transformations:

<!-- Date Pipe -->
<p>{{ currentDate | date:'short' }}</p>

<!-- Currency Pipe -->
<p>{{ price | currency:'USD' }}</p>

<!-- Uppercase/Lowercase -->
<p>{{ text | uppercase }}</p>
<p>{{ text | titlecase }}</p>
Enter fullscreen mode Exit fullscreen mode

Custom Pipe

Create custom pipes for specific data transformations:

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

@Pipe({
  name: 'truncate',
  pure: true
})
export class TruncatePipe implements PipeTransform {
  transform(value: string, limit: number = 50): string {
    if (!value || value.length <= limit) return value;
    return value.substring(0, limit) + '...';
  }
}
Enter fullscreen mode Exit fullscreen mode

Async Pipe

Handle asynchronous data with the async pipe:

// Template
<div *ngIf="businesses$ | async as businesses">
  <div *ngFor="let business of businesses">
    {{ business.name }}
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Best Practices

  1. Use structural directives for conditional rendering
  2. Create custom directives for reusable DOM manipulation
  3. Use pipes for data transformation - Not for business logic
  4. Keep pipes pure when possible - Better performance
  5. Use async pipe - Automatically handles Observables and Promises
  6. Use trackBy function with *ngFor - Better performance with large lists

📖 Read the Complete Guide

This is just a brief overview! The complete guide on my blog includes:

  • Custom Attribute Directives - Highlight, tooltip, and permission directives
  • Advanced Structural Directives - appUnless directive example
  • Complete Built-in Pipes - All date formats, currency options, keyvalue pipe
  • Chaining Pipes - Combining multiple pipes
  • Pure vs Impure Pipes - Performance considerations
  • Multiple Async Pipes - Handling multiple observables
  • Performance Tips - Best practices for optimization
  • Real-world examples from production applications

👉 Read the full article with all code examples here


What's your experience with Angular Directives and Pipes? Share your tips in the comments! 🚀

For more Angular guides, check out my blog covering Reactive Forms, Component Communication, Services, and more.

Top comments (0)