Skip to content
← All writing
Article · 2 min read Article By Abidh Muhsin

Decorator-Based Selective Loader for Angular HTTP Requests

Learn how to implement a selective page-level loader for specific HTTP requests in Angular using decorators. Control which requests show loaders without cluttering your code.

Decorator-Based Selective Loader

Table of contents

Open Table of contents

The Problem

In enterprise Angular applications, you often need to show a loader while specific HTTP requests are in progress. The challenge? Not all requests need the same treatment:

  • Some requests require a full-page loader blocking user interaction
  • Other requests are background calls that shouldn’t block the UI
  • Some might need section-specific loaders
  • Managing this selectively across your entire app becomes tedious and repetitive

Traditional approaches require manually calling showLoader() and hideLoader() before and after every HTTP call, cluttering your code and breaking DRY principles.

The Solution: Decorators

Instead of sprinkling loader logic throughout your code, use a simple decorator:

@LoaderEnabled()
getSomeData(): Observable<any> {
  return this.http.get('/api/data');
}

That’s it! The loader is automatically managed for that request alone—no additional code needed.

How It Works

The implementation involves three key components:

1. Loader Component & Service

Create a shared LoaderComponent that displays globally and a LoaderService that manages the loader state:

  • Display a centered loader with backdrop
  • Disable user interactions while loader is active
  • Manage show/hide through a flag in the service

2. The Decorator

The @LoaderEnabled() decorator is the magic:

export function LoaderEnabled() {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;

    descriptor.value = function (...args: any[]) {
      LoaderService.showLoader();

      const result = originalMethod.apply(this, args);

      if (result instanceof Observable) {
        return result.pipe(
          map(data => {
            LoaderService.hideLoader();
            return data;
          }),
          catchError(error => {
            LoaderService.hideLoader();
            throw error;
          })
        );
      }

      return result;
    };

    return descriptor;
  };
}

What it does:

  • Injects showLoader() call before the method executes
  • Wraps the Observable with map and catchError operators
  • Calls hideLoader() when the HTTP request completes (success or error)
  • Preserves the original method functionality

3. Usage

// Show loader for this specific request
@LoaderEnabled()
getUsers(): Observable<User[]> {
  return this.http.get<User[]>('/api/users');
}

// No loader for background requests
getBackgroundData(): Observable<any> {
  return this.http.get('/api/background');
}

// Even use on interceptor for all requests
@LoaderEnabled()
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  return next.handle(req);
}

Key Benefits

  • Clean & DRY - One decorator line instead of repeating loader logic everywhere
  • Selective - Control exactly which requests show loaders
  • Maintainable - Changes to loader behavior happen in one place
  • Type-Safe - Works seamlessly with TypeScript and Angular services
  • Flexible - Use on any method returning an Observable

Advanced Improvements

The article also covers several enhancements:

  1. Delayed Loader - Only show loader after 200ms to avoid flickering on quick requests
  2. Request Counter - Track concurrent requests to avoid hiding loader prematurely
  3. Selective Interception - Combine with HttpInterceptor for smarter loader management

Read the Full Article

Originally published for Medium - Written during my early Angular journey.

For complete implementation details, working demos, and StackBlitz code:

📖 Decorator-Based Loader for Angular HttpClient

The article includes full code examples, architecture diagrams, and a live working demo you can explore and customize.

Key Takeaways

Decorators are powerful tools for reducing boilerplate code in Angular. This decorator-based approach solves a common problem elegantly without:

  • Modifying standard Angular HttpClient
  • Cluttering your service methods
  • Breaking inheritance or extending classes
  • Sacrificing flexibility or control

If you’re building enterprise Angular applications, this pattern is worth adopting for any cross-cutting concerns like loaders, logging, or request tracking.

Read next

Closest to this one
  1. 01AccuServeProduct · 2023
  2. 02Building a High-Performance Image Resizer Proxy with GoArticle · 2 min
  3. 03Agentic support frameworkProduction work · Cambium