Skip to the solution
MediumFrontend9 min read

What is a directive and what are the types?

837 views

The problem

Question presented to candidate: "What is a directive in Angular? Walk me through the different types, give an example of each, and tell me when you would write your own."

What a strong answer should cover:

  • A directive is a class with @Directive metadata that Angular attaches to elements matching its selector, to add behaviour or change appearance.
  • Components are directives with a template (@Component extends @Directive).
  • Attribute directives change the look or behaviour of their host element (NgClass, NgStyle, NgModel, a custom appHighlight), typically through host bindings and listeners.
  • Structural directives add or remove DOM by stamping out an ng-template via TemplateRef and ViewContainerRef (*ngIf, *ngFor, custom *appHasRole); the built-in three are now replaced by @if / @for / @switch.
  • Host directives (directive composition API, v15+) let a component or directive apply other directives to its own host without inheritance.
  • Directives are standalone by default and must be imported where used.

Clarifying questions expected:

  • "Do you want the conceptual categories, or how to build one?"

Code / implementation expected: Yes — a custom attribute directive, ideally also a structural one.

  • directives

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

9 min read · 10 sections

Read the code

AngularAn attribute directive, a structural directive, and a component composed with hostDirectives
import { Component, Directive, Input, TemplateRef, ViewContainerRef, inject, signal } from "@angular/core";

// Attribute directive: changes the look or behaviour of the element it sits on.
@Directive({
  selector: "[appHighlight]",
  host: {
    "[style.background]": "active ? color : null",
    "(mouseenter)": "active = true",
    "(mouseleave)": "active = false",
  },
})
export class Highlight {
  @Input("appHighlight") color = "gold";
  active = false;
}

// A tiny reusable behaviour, composed into a component with hostDirectives.
@Directive({ selector: "[appTooltip]", host: { "[attr.title]": "tip" } })
export class Tooltip {
  @Input() tip = "";
}

// Structural directive: adds or removes DOM by stamping out its <ng-template>.
@Directive({ selector: "[appRepeat]" })
export class Repeat {
  private tpl = inject(TemplateRef<{ $implicit: number }>);
  private vcr = inject(ViewContainerRef);
  @Input() set appRepeat(times: number) {
    this.vcr.clear();
    for (let i = 0; i < times; i++) this.vcr.createEmbeddedView(this.tpl, { $implicit: i + 1 });
  }
}

// Component: a directive with its own template.
@Component({
  selector: "app-badge",
  hostDirectives: [{ directive: Tooltip, inputs: ["tip"] }],
  template: `<span class="badge"><ng-content /></span>`,
})
export class Badge {}

@Component({
  selector: "app-root",
  imports: [Highlight, Repeat, Badge],
  template: `
    <p appHighlight="lightblue">Hover me</p>
    <ul><li *appRepeat="count(); let n">Row {{ n }}</li></ul>
    <app-badge tip="Composed with hostDirectives">new</app-badge>
    <button (click)="count.set(count() + 1)">more rows</button>
  `,
})
export class AppComponent {
  count = signal(2);
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 31 of 121 in Angular

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Angular questions
Up nextMedium

How do you handle dynamic validation where one form field's validator depends on another field's value?

Continue