Angular Decorators


Angular Decorators Interview with follow-up questions

1. What are decorators in Angular?

Decorators are functions that attach metadata to a class, property, method, or parameter, written with @ immediately before the target. Angular's compiler reads this metadata to know how to build and wire the app — what's a component, what gets injected, what's an input, and so on.

The categories to know:

  • Class: @Component, @Directive, @Injectable, @Pipe, (legacy) @NgModule.
  • Property: @Input, @Output, @ViewChild, @ContentChild, @HostBinding.
  • Method/parameter: @HostListener; and @Inject, @Optional, @Self for DI.

The 2026 nuance worth stating: these are TypeScript's legacy/experimental decorators (driven by Angular's compiler), not the newer TC39 standard decorators. And Angular is actively providing decorator-free, signal-based replacementsinput(), output(), model(), viewChild(), and inject() — which are preferred in new code. Knowing both the decorators and their signal equivalents is what current interviews look for.

↑ Back to top

Follow-up 1

Can you explain the different types of decorators in Angular?

In Angular, there are several types of decorators:

  1. Class decorators: These decorators are applied to classes and can modify the class itself or its constructor.

  2. Property decorators: These decorators are applied to class properties and can modify the behavior of the property.

  3. Method decorators: These decorators are applied to class methods and can modify the behavior of the method.

  4. Parameter decorators: These decorators are applied to method parameters and can modify the behavior of the parameter.

Each type of decorator serves a different purpose and can be used to add additional functionality or modify the behavior of the decorated element.

Follow-up 2

What is the purpose of the @Component decorator?

The @Component decorator is used to define a component in Angular. It is applied to a class and provides metadata about the component, such as its selector, template or templateUrl, styles or styleUrls, and more. The @Component decorator allows Angular to understand and instantiate the component when it is used in a template or by another component.

Follow-up 3

How does the @Injectable decorator work?

The @Injectable decorator is used to mark a class as injectable. It is applied to a service class and allows Angular's dependency injection system to provide instances of the service to other classes that depend on it. When a class is marked with the @Injectable decorator, Angular will create a single instance of the service and inject it wherever it is requested.

Follow-up 4

What are parameter decorators?

Parameter decorators are decorators that are applied to method parameters. They allow you to modify the behavior of the parameter or provide additional metadata about the parameter. Parameter decorators are defined using the @ symbol followed by the decorator name, and they are applied immediately before the parameter declaration in the method signature.

Follow-up 5

Can you give an example of a custom decorator?

Sure! Here's an example of a custom decorator in Angular:

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

  descriptor.value = function (...args: any[]) {
    console.log(`Calling method ${propertyKey} with arguments:`, args);
    const result = originalMethod.apply(this, args);
    console.log(`Method ${propertyKey} returned:`, result);
    return result;
  };

  return descriptor;
}

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

const example = new Example();
example.greet('John');

In this example, the log decorator is applied to the greet method of the Example class. When the greet method is called, the decorator logs the method arguments before and after the method execution. This allows you to add custom behavior to methods without modifying their original implementation.

2. How do decorators contribute to Angular's modular design?

Decorators are the declarative glue that lets Angular assemble an app from independent, self-describing pieces. By attaching metadata rather than wiring things imperatively, they enable the framework's modular features:

  • @Injectable + @Inject power dependency injection, so classes declare what they need and stay loosely coupled and swappable.
  • @Component/@Directive declare self-contained UI units with their own selectors, templates, and (in standalone) their own imports — the basis of composability.
  • @Input/@Output define a component's public contract, enabling reuse without exposing internals.
  • @Pipe packages reusable transformation logic.

The result is that each building block is independently declared, testable, and tree-shakable. A current note: modern Angular pushes this modularity further with standalone components (no NgModule needed) and signal-based APIs (input(), inject()) that achieve the same wiring with less boilerplate — but the underlying idea, metadata-driven composition, is the same.

↑ Back to top

Follow-up 1

How does the @NgModule decorator help in organizing an Angular application?

The @NgModule decorator is used to define a module in Angular. Modules are a way to organize and encapsulate related components, directives, pipes, and services. The @NgModule decorator allows you to specify the metadata for a module, such as the list of components, directives, and pipes it exports, the providers it makes available for dependency injection, and more. By using the @NgModule decorator, you can create reusable and self-contained modules that can be easily imported and used in other parts of your application.

Follow-up 2

What is the role of the @Directive decorator?

The @Directive decorator is used to define a directive in Angular. Directives are a way to extend the behavior of HTML elements or components. They allow you to attach custom behavior to elements, such as handling user interactions, manipulating the DOM, or adding custom styling. The @Directive decorator allows you to specify the metadata for a directive, such as the selector that identifies the elements to which the directive applies, the inputs and outputs it provides, and more.

Follow-up 3

Can you explain how decorators enable dependency injection?

Dependency injection is a key feature of Angular that allows you to easily manage and inject dependencies into your classes. Decorators play a crucial role in enabling dependency injection in Angular. By using the @Injectable decorator, you can mark a class as injectable, which means that Angular's dependency injection system can create instances of that class and inject its dependencies. The @Inject decorator is used to specify the dependencies that should be injected into a class. Decorators provide the necessary metadata for Angular's dependency injection system to resolve and inject the correct dependencies at runtime.

Follow-up 4

What is the significance of the @Input and @Output decorators?

The @Input and @Output decorators are used to define input and output properties in Angular components. The @Input decorator is used to mark a property as an input property, which means that it can receive values from its parent component. The @Output decorator is used to mark a property as an output property, which means that it can emit events to its parent component. These decorators provide a way to establish communication between components, allowing data to flow from parent components to child components (via input properties) and from child components to parent components (via output properties and events).

Follow-up 5

How do decorators facilitate component interaction?

Decorators in Angular facilitate component interaction by providing a way to define input and output properties, as well as emit events. Input properties allow parent components to pass data to child components, while output properties and events allow child components to communicate with their parent components. By using decorators such as @Input and @Output, you can establish a clear and structured way for components to interact with each other, enabling the building of complex and reusable component-based applications.

3. What is the difference between a decorator and a regular function in Angular?

A regular function runs when you call it and does work or returns a value. A decorator is a special function that's applied with @ to a declaration (class, property, method, parameter) and runs at definition time to attach metadata or modify how that declaration behaves — you don't call it yourself; the runtime/compiler applies it.

Concretely: @Component({...}) doesn't "run" when your component renders — it executes once when the class is defined, recording metadata Angular later reads to instantiate and render the component. A plain function like formatDate(d) is invoked explicitly wherever you need it.

The deeper point interviewers like: a decorator is implemented as a function (it receives the target as an argument), so the distinction isn't "function vs not-a-function" — it's how and when it's applied. In Angular specifically, decorators feed the compiler, which is why their metadata must be statically analyzable (you can't build a decorator's config from arbitrary runtime values).

↑ Back to top

Follow-up 1

Can you explain how decorators are used in Angular's metadata?

In Angular, decorators are extensively used to provide metadata for classes, methods, properties, and parameters. The metadata is used by Angular's compiler and runtime to understand and process the decorated elements. For example, the @Component decorator is used to provide metadata for a component class, specifying its selector, template, styles, and other configuration options. Similarly, the @Input and @Output decorators are used to define input and output properties of a component, which are used for data binding and communication between components.

Follow-up 2

How does Angular process decorators?

Angular processes decorators by analyzing the metadata provided by the decorators and using it to generate the necessary code and configuration. During the compilation process, Angular's compiler reads the decorators and their metadata, and based on that, it generates the necessary JavaScript code, HTML templates, and CSS styles. At runtime, Angular's runtime engine uses the metadata provided by the decorators to instantiate and configure the components, apply data binding, and handle other aspects of the application's behavior.

Follow-up 3

What is the role of decorators in Angular's compilation process?

Decorators play a crucial role in Angular's compilation process. They provide the necessary metadata that Angular's compiler uses to generate the code and configuration required for the application to run. The metadata provided by decorators helps the compiler understand the structure and behavior of the application's components, directives, and other elements. It allows the compiler to perform optimizations, generate efficient code, and handle various aspects of the application's functionality, such as dependency injection, change detection, and template rendering.

Follow-up 4

Can you provide an example of a decorator modifying a class or property?

Sure! Here's an example of a decorator modifying a class:

function LogClass(target: any) {
  console.log('Class:', target);
}

@LogClass
class MyClass {
  // class implementation
}

In this example, the LogClass decorator is applied to the MyClass class. When the class is instantiated, the decorator's logic is executed, and it logs the class to the console.

And here's an example of a decorator modifying a property:

function LogProperty(target: any, key: string) {
  console.log('Property:', key);
}

class MyClass {
  @LogProperty
  myProperty: string;
}

In this example, the LogProperty decorator is applied to the myProperty property of the MyClass class. When an instance of MyClass is created, the decorator's logic is executed, and it logs the property name to the console.

Follow-up 5

How do decorators contribute to Angular's declarative programming style?

Decorators play a significant role in Angular's declarative programming style. By using decorators, developers can express the desired behavior and configuration of components, directives, and other elements in a declarative manner. Instead of manually writing complex code to achieve certain functionalities, decorators allow developers to simply apply the appropriate decorators and provide the necessary metadata. This approach makes the code more readable, maintainable, and easier to understand. It also promotes the separation of concerns and allows for better reusability of code.

4. How does the @HostBinding and @HostListener decorators work?

Both bind a component/directive class to its host element (the element the selector matches):

  • @HostBinding('property') binds a class member to a property, attribute, class, or style on the host. Updating the field updates the host element.
  • @HostListener('event', ['$event']) subscribes a method to an event on the host (or window/document), running it when the event fires.
@Directive({ selector: '[appButton]' })
export class ButtonDirective {
  @HostBinding('class.active') isActive = false;
  @HostListener('click') toggle() { this.isActive = !this.isActive; }
}

The modern note worth adding: the same thing can be done with the host metadata object in the @Component/@Directive decorator (host: { '[class.active]': 'isActive', '(click)': 'toggle()' }), which the Angular team often recommends, and host bindings increasingly read from signals. These decorators are heavily used to build reusable attribute directives without touching ElementRef/Renderer2 directly.

↑ Back to top

Follow-up 1

Can you provide an example of using @HostBinding?

Sure! Here's an example:

import { Component, HostBinding } from '@angular/core';

@Component({
  selector: 'app-example',
  template: '<div>Example Component</div>',
  styles: ['div { background-color: yellow; }']
})
export class ExampleComponent {
  @HostBinding('style.backgroundColor') backgroundColor = 'red';
}

In this example, the @HostBinding decorator is used to bind the backgroundColor property of the component to the style.backgroundColor property of the host element. This sets the background color of the host element to red.

Follow-up 2

What is the purpose of the @HostListener decorator?

The @HostListener decorator allows you to listen to events on the host element and execute a method in response to those events. It binds a method of the component to an event of the host element. This can be useful when you want to add custom behavior to the host element based on user interactions or other events.

For example, you can use the @HostListener decorator to listen to the click event on the host element and execute a method that performs some action when the element is clicked.

Follow-up 3

How do these decorators contribute to component encapsulation?

The @HostBinding and @HostListener decorators contribute to component encapsulation by allowing you to interact with the host element from within the component class. They provide a way to bind component properties to host element properties and listen to host element events, without exposing the implementation details of the host element to the outside world.

This helps to keep the component self-contained and encapsulated, as the logic for interacting with the host element is contained within the component class.

Follow-up 4

Can you explain how these decorators can be used for custom attribute directives?

Yes, the @HostBinding and @HostListener decorators can also be used with custom attribute directives. When used with a custom attribute directive, the @HostBinding decorator can be used to bind a property of the directive to a property of the host element, and the @HostListener decorator can be used to listen to events on the host element and execute a method in response to those events.

This allows you to add custom behavior to the host element based on the presence of the attribute directive, without modifying the component that uses the directive.

Follow-up 5

What are some common use cases for these decorators?

Some common use cases for the @HostBinding and @HostListener decorators include:

  • Modifying the host element's appearance or behavior based on component state or user interactions.
  • Adding custom behavior to the host element based on events or interactions.
  • Interacting with the host element in a custom attribute directive.

These decorators provide a way to interact with the host element in a flexible and encapsulated manner, allowing you to customize the behavior and appearance of your components.

5. What is the purpose of the @ViewChild and @ViewChildren decorators?

Both query a component's own template (its view) for child elements, components, or directives so the parent can interact with them:

  • @ViewChild returns the first match (a single reference).
  • @ViewChildren returns a QueryList of all matches.
@ViewChild('search') input!: ElementRef;
@ViewChildren(ItemComponent) items!: QueryList;

ngAfterViewInit() { this.input.nativeElement.focus(); }

Gotchas interviewers probe: view-query results aren't available until ngAfterViewInit (or ngAfterViewChecked); a static: true query resolves earlier in ngOnInit but only for elements not inside conditionals; and @ContentChild/@ContentChildren are the counterparts for projected (ng-content) content, not the view.

The current best-practice answer: prefer the signal-based queries viewChild(), viewChildren(), contentChild(), and contentChildren() in new code. They return signals (and viewChild.required()), so you read them reactively in computed()/effect() without worrying about lifecycle timing.

↑ Back to top

Follow-up 1

Can you explain how these decorators are used to access child components?

To access a child component using @ViewChild, you need to define a template reference variable for the child component in the parent component's template. Then, you can use @ViewChild decorator to get a reference to the child component in the parent component's class. This allows you to access the child component's properties and methods.

Example:

Parent Component Template:


Parent Component Class:

import { ViewChild } from '@angular/core';
import { ChildComponent } from './child.component';

export class ParentComponent {
  @ViewChild('childComponent') childComponent: ChildComponent;

  ngAfterViewInit() {
    // Access child component properties and methods
    this.childComponent.someMethod();
  }
}

Follow-up 2

What is the difference between @ViewChild and @ViewChildren?

The main difference between @ViewChild and @ViewChildren is that @ViewChild returns a single instance of the child component or element, while @ViewChildren returns a QueryList containing multiple instances of the child component or element.

@ViewChild is used when you want to access a single child component or element, while @ViewChildren is used when you want to access multiple child components or elements.

Follow-up 3

Can you provide an example of using these decorators?

Sure! Here's an example of using @ViewChild and @ViewChildren decorators:

Parent Component Template:



Parent Component Class:

import { ViewChild, ViewChildren, QueryList } from '@angular/core';
import { ChildComponent } from './child.component';

export class ParentComponent {
  @ViewChild('childComponent') childComponent: ChildComponent;
  @ViewChildren('childComponent') childComponents: QueryList;

  ngAfterViewInit() {
    // Access single child component properties and methods
    this.childComponent.someMethod();

    // Access multiple child components properties and methods
    this.childComponents.forEach(child =&gt; child.someMethod());
  }
}

Follow-up 4

How do these decorators contribute to component interaction?

The @ViewChild and @ViewChildren decorators contribute to component interaction by allowing a parent component to access and interact with its child components or elements. This enables communication and coordination between different parts of the application, as the parent component can call methods or access properties of its child components.

Follow-up 5

What are some common use cases for these decorators?

Some common use cases for @ViewChild and @ViewChildren decorators include:

  1. Accessing child components or elements to perform actions or retrieve data.
  2. Communicating between parent and child components by calling methods or accessing properties.
  3. Manipulating the DOM or applying styles to child elements.
  4. Triggering animations or other visual effects on child components.
  5. Validating form inputs or performing form-related operations on child components.

These decorators are particularly useful when building complex component hierarchies or when components need to interact with each other.

Live mock interview

Mock interview: Angular Decorators

Intermediate ~5 min Your own free AI key

Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.