How would you create a custom *appDelay structural directive?

This tests Angular rendering internals. A strong answer covers: TemplateRef as the embedded template, ViewContainerRef as insertion anchor, and a setter that creates the embedded view after a delay. Mention OnDestroy cleanup.
WHAT THIS TESTS: This question probes whether you understand how Angular renders templates outside of component sugar. Structural directives are not DOM manipulation helpers; they are instructions to the compiler that turn a template element into an embedded view managed by the view container. The interviewer wants to see if you know the difference between a template definition and a live view, and whether you can manage the lifecycle of dynamically created views correctly.
A GOOD ANSWER COVERS: A strong response walks through the implementation in five parts. First, the directive class must be decorated with Directive and configured with a selector matching the structural microsyntax, typically appDelay. Second, inject both TemplateRef and ViewContainerRef in the constructor. TemplateRef gives you the template defined by the starred element, while ViewContainerRef provides the anchor point in the parent view where embedded views can be attached or detached. Third, expose an input setter such as set appDelay so Angular binds the delay value whenever the microsyntax expression changes. Inside that setter, schedule a timer. Fourth, when the timer fires, call this.viewContainer.createEmbeddedView(this.templateRef) to instantiate the template into a real view and insert it into the DOM. Fifth, implement OnDestroy and clear any pending timeout to prevent memory leaks and dangling views. If the input changes before the timer fires, a robust solution also clears the previous timeout and restarts the countdown.
COMMON WRONG ANSWERS: Red flags include describing the directive as an attribute directive that mutates the host element, or suggesting Renderer2 and ElementRef to hide or show content after a delay. That misses the point entirely because structural directives never touch the host element directly; they control whether the template is instantiated at all. Another red flag is forgetting to clean up the setTimeout or the created view, which leaks memory and can cause ExpressionChangedAfterItHasBeenCheckedError if the timer fires after the component destroys. Some candidates also confuse TemplateRef with the actual DOM and think it is the rendered output rather than the unmounted template definition.
LIKELY FOLLOW-UPS: The interviewer may ask how you would handle an input change that shortens or cancels the pending delay. They might also ask how to pass context variables into the embedded view, which involves the second argument to createEmbeddedView. A deeper follow-up is how Angular's new built-in control flow and deferrable views change the need for custom structural directives in modern Angular, or how signals might simplify the timing logic.
ONE CONCRETE EXAMPLE: Imagine a directive named DelayDirective with selector appDelay. The constructor receives private templateRef of type TemplateRef and private viewContainer of type ViewContainerRef. The input setter set appDelay receives ms as a number, stores the delay, clears any existing timeout with clearTimeout, then calls setTimeout. Inside the timeout callback, this.viewContainer.createEmbeddedView(this.templateRef) runs, turning the template into a view attached at the directive's anchor. The ngOnDestroy method calls clearTimeout on the stored handle and optionally this.viewContainer.clear to remove any already-inserted views.
Read the original → angular.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.