Understanding Custom Decorators in Angular

Sagarnath S
3 min readFeb 10, 2024
Angular: Custom Decorators

Decorators are functions that modify classes, methods, properties, or parameters in a declarative way. While Angular provides several built-in decorators like @Component, @Directive, and @Injectable, developers can also create custom decorators to encapsulate reusable logic and streamline code organization.

Before we dive into custom decorators, it’s essential to grasp the basics of decorators in Angular. Decorators are implemented as functions prefixed with the @ symbol and are applied to classes, class members (such as methods and properties), or method parameters. They enable developers to enhance the behavior of these elements without modifying their underlying implementation directly. Decorators are widely used for tasks like dependency injection, metadata annotation, and aspect-oriented programming.

Creating Custom Decorators:

Custom decorators in Angular are created using TypeScript. To define a custom decorator, you need to create a function that accepts parameters corresponding to the target element being decorated. These parameters include the target class for class decorators, the prototype for method decorators, and the target object for property decorators. Additionally, custom decorators can take configuration options and return a new function or manipulate the target directly.

Here are examples of different types of custom decorators:

Class Decorator:

Class decorators are applied to classes and can be used to modify or enhance the behavior of the class as a whole. One common use case for class decorators is to apply metadata or configure class-level settings.

function InjectableService(config: { providedIn: 'root' | 'any' }) {
return function (target: any) {
if (config.providedIn === 'root') {
// Logic to provide the service in root injector
} else {
// Logic to provide the service in any injector
}
};
}

@InjectableService({ providedIn: 'root' })
class ExampleService {
// Service implementation
}

Method Decorator:

Method decorators are applied to methods within a class and can intercept method calls, modify behavior, or add additional functionality.

function LogMethod(target: any, key: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;

descriptor.value = function (...args: any[]) {
console.log(`Executing ${key} with arguments: ${JSON.stringify(args)}`);
const result = originalMethod.apply(this, args);
console.log(`Method ${key} executed with result: ${JSON.stringify(result)}`);
return result;
};

return descriptor;
}

class ExampleService {
@LogMethod
greet(name: string): string {
return `Hello, ${name}!`;
}
}

const exampleService = new ExampleService();
exampleService.greet('John');

Property Decorator:

Property decorators are applied to properties within a class and can intercept property access, modify property values, or add additional metadata.

function DefaultValue(defaultValue: any) {
return function (target: any, key: string) {
let value = defaultValue;

Object.defineProperty(target, key, {
get: function () {
return value;
},
set: function (newValue) {
value = newValue !== undefined ? newValue : defaultValue;
},
enumerable: true,
configurable: true
});
};
}

class ExampleComponent {
@DefaultValue('John')
name: string;

constructor() {
console.log(this.name); // Output: 'John'
}
}

const exampleComponent = new ExampleComponent();

Parameter Decorator:

Parameter decorators are applied to parameters of methods within a class and can intercept method parameter values or add additional metadata.

function ValidateParameter() {
return function (target: any, key: string, index: number) {
// Logic to validate parameter value
};
}

class ExampleService {
greet(@ValidateParameter() name: string): string {
return `Hello, ${name}!`;
}
}

These examples demonstrate the versatility of custom decorators in Angular and how they can be used to extend and customize the behavior of classes and their members. By leveraging custom decorators effectively, developers can enhance code readability, maintainability, and reusability in Angular applications.

Thank you for reading if you have any doubts. drop the message in comments.

Follow me on Medium or LinkedIn to read more about Angular and TS!

--

--

Sagarnath S

Software Development Engineer - I @CareStack || Web Developer || Angular || ASP.Net Core || C# || TypeScript || HTML || CSS