DEV Community

Cover image for Master Angular Directives & Pipes: Writing Cleaner, Reusable Code πŸ› οΈ
Md. Maruf Rahman
Md. Maruf Rahman

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

Master Angular Directives & Pipes: Writing Cleaner, Reusable Code πŸ› οΈ

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)