Angular - Decorators & Metadata


Decorators are special functions used to add metadata, modify behavior, or add some additional functionalities to classes, methods, properties, or parameters in programming languages like TypeScript or JavaScript.

In Angular, each decorator has a base configuration with some default values and you can change or update it according to the project's need. It is defined using the @ symbol followed by a function name. This symbol helps Angular to recognize decorators.

Decorators in Angular

Angular provides the following decorators −

The @Component Decorator

The @Component decorator is used to define a component in Angular. A component generates a section of web page called View and this decorator helps Angular understand the metadata related to the component.

Example

The following example shows @component decorator in an angular component.

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-my-component',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './my-component.component.html',
  styleUrl: './my-component.component.css'
})
export class MyComponent {
  // your code
}

The metadata included in the above example is selector, imports, templateUrl, and styleUrl. They define how the component should be displayed in the DOM.

The @Injectable Decorator

If a TypeScript class in Angular is decorated by @Injectable decorator, Angular will consider it as a service that can be injected into other classes.

Example

Let's see an example of @Injectable decorator.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class MyService {
  // your service code
}

By marking a service with @Injectable, Angular knows to create and inject the service wherever it's needed in the application.

The @NgModule Decorator

The @NgModule decorator is used to define an Angular module. A module is a collection of related components, services, pipes, and directives that are bundled together.

Example

Here is an example of @NgModule decorator −

@NgModule({
   declarations: [MyComponent],
   imports: [CommonModule],
   providers: [MyService]
})
export class MyModule {}

The @NgModule decorator tells Angular about which components, directives, and pipes are part of the module and which other modules are imported.

The @Directive Decorator

The @Directive decorator is used to define a custom directive, which can modify the behavior or appearance of elements in the DOM.

Example

The example given below shows a custom directive that modifies the background color of any element it's applied to.

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

@Directive({
  selector: '[appHighlight]',
  standalone: true,
  imports: [CommonModule]
})
export class HighlightDirective {
  constructor(private el: ElementRef) {
    this.el.nativeElement.style.backgroundColor = 'yellow';
  }
}

The @Input Decorator

The @Input decorator decorator is used in components to define inputs for property binding. It helps data to be passed into the component.

Example

In the following, we will see how to use @Input decorator within a component.

@Component({
   selector: 'app-child',
   template: `<div>{{childData}}</div>`
})
export class ChildComponent {
   @Input() childData: string;
}

The @Output Decorator

Child component can send the data to parent component through the @Output decorator. This decorator is actually an event emitter that passes the data (output) along with event.

Example

The following example shows the use of @Output decorator.

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `
    <div>{{childData}}</div>
    <button (click)="sendData()">Send Data</button>
  `
})
export class ChildComponent {
  @Input() childData: string;
  @Output() dataEmitter = new EventEmitter<string>();

  sendData() {
    this.dataEmitter.emit(this.childData);
  }
}

The @Pipe Decorator

The @Pipe decorator in Angular is used to define custom pipes, which transform data in templates.

Example

Here is an example of @Pipe decorator.

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

@Pipe({ name: 'capitalize' })
export class CapitalizePipe implements PipeTransform {
  transform(value: string): string {
    return value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
  }
}

This CapitalizePipe transforms the first letter of a string to uppercase and the rest to lowercase.

What Is Metadata in Angular?

In Angular, Metadata is the information that is attached to classes and other elements to define their behavior. It is defined via decorators, as we saw earlier. When Angular processes a component or service, it reads the metadata to configure the element's behavior.

Example

Let's see the metadata mentioned inside an Angular @Component decorator −

@Component({
   selector: 'app-my-component',   
   standalone: true,
   imports: [CommonModule],
   templateUrl: './my-component.component.html',  
   styleUrls: ['./my-component.component.css'],  
})

Here,

  • selector specifies the HTML tag to use for this component.

  • templateUrl points to the location of the HTML template file.

  • styleUrls specifies the location of the CSS files that define the component's styling.