Hone logo
Hone
Problems

Implementing a Custom ngSwitch Directive in Angular

This challenge asks you to implement a simplified version of Angular's ngSwitch directive. ngSwitch allows you to conditionally render different templates based on the value of an expression. Building this directive will solidify your understanding of Angular directives, template parsing, and conditional rendering.

Problem Description

You need to create an Angular directive called CustomNgSwitch that mimics the core functionality of Angular's ngSwitch. The directive should:

  1. Accept an input property called ngSwitch: This property will hold the expression whose value will be used for switching.
  2. Accept multiple input properties named ngSwitchCase: Each ngSwitchCase property will hold a value. The corresponding template for a ngSwitchCase will be rendered if the ngSwitch expression matches the ngSwitchCase value.
  3. Accept a default template: If none of the ngSwitchCase values match the ngSwitch expression, a default template should be rendered. This default template is identified by ngSwitchDefault.
  4. Render the appropriate template: Based on the value of the ngSwitch expression, the directive should render the template associated with the matching ngSwitchCase or the ngSwitchDefault template if no match is found.

Key Requirements:

  • The directive must be a structural directive (using *ngSwitch).
  • The directive must dynamically create and render the appropriate template based on the input values.
  • The directive should handle cases where no ngSwitchCase matches the ngSwitch expression.

Expected Behavior:

When the ngSwitch expression changes, the directive should re-evaluate the ngSwitchCase values and render the corresponding template. If no ngSwitchCase matches, the ngSwitchDefault template should be rendered.

Edge Cases to Consider:

  • ngSwitch expression is null or undefined.
  • No ngSwitchCase directives are present.
  • Multiple ngSwitchCase directives have the same value. (The first one encountered should take precedence).
  • ngSwitchDefault is not present.

Examples

Example 1:

Input:
Template:
<div *customNgSwitch="expression">
  <div *ngSwitchCase="1">Case 1</div>
  <div *ngSwitchCase="2">Case 2</div>
  <div *ngSwitchDefault>Default</div>
</div>
expression = 2

Output:
<div>
  <div>Case 2</div>
</div>
Explanation: The expression is 2, which matches the value of ngSwitchCase="2". Therefore, the template associated with that case is rendered.

Example 2:

Input:
Template:
<div *customNgSwitch="expression">
  <div *ngSwitchCase="'A'">Case A</div>
  <div *ngSwitchCase="'B'">Case B</div>
  <div *ngSwitchDefault>Default</div>
</div>
expression = 'C'

Output:
<div>
  <div>Default</div>
</div>
Explanation: The expression is 'C', which does not match either 'A' or 'B'. Therefore, the default template is rendered.

Example 3: (Edge Case)

Input:
Template:
<div *customNgSwitch="expression">
  <div *ngSwitchCase="1">Case 1</div>
  <div *ngSwitchCase="1">Case 1 Duplicate</div>
  <div *ngSwitchDefault>Default</div>
</div>
expression = 1

Output:
<div>
  <div>Case 1</div>
</div>
Explanation: Although there are two ngSwitchCase directives with the value 1, only the first one is considered.

Constraints

  • The directive must be implemented in TypeScript.
  • The directive should be compatible with Angular version 14 or higher.
  • The directive should not rely on external libraries.
  • The directive should be performant enough to handle a reasonable number of ngSwitchCase directives (e.g., up to 10). Avoid unnecessary DOM manipulations.
  • The ngSwitch expression can be any primitive type (string, number, boolean).

Notes

  • Consider using TemplateRef and ViewContainerRef to dynamically create and render templates.
  • Think about how to efficiently store and compare the ngSwitchCase values.
  • Pay close attention to the structural directive syntax (*customNgSwitch).
  • Remember that Angular's change detection will automatically trigger re-evaluation when the ngSwitch expression changes.
  • Focus on the core functionality of ngSwitch. Advanced features like ngSwitchWhen are not required for this challenge.
Loading editor...
typescript