Hone logo
Hone
Problems

Mastering viewChild with Signals in Angular

Angular's Signals offer a powerful new paradigm for managing state and reactivity. This challenge focuses on integrating viewChild, a crucial mechanism for accessing DOM elements and child components, with Angular's Signals API. You will learn how to declaratively access and react to DOM elements within your components using the modern Signals approach.

Problem Description

Your task is to create an Angular component that dynamically displays a count and an input field. The component should use viewChild with Signals to access a div element that will serve as a counter display. When the user types into the input field, the text should be reflected in the div element using the viewChild signal.

Key Requirements:

  1. Component Structure: Create a component with a template that includes an <input type="text"> and a <div> element.
  2. viewChild with Signal: Use the viewChild decorator from @angular/core to obtain a reference to the div element. This reference must be managed as an Angular Signal.
  3. Input Binding: Bind the input field's value to a component property, preferably using Signals.
  4. Updating the div: When the input field's value changes, update the content of the div element. This update should be driven by the viewChild signal and the input signal.
  5. Initial State: The div should initially display a default message (e.g., "Type something...").

Expected Behavior:

  • As the user types into the input field, the text typed should immediately appear inside the div element.
  • The div element should always reflect the current value of the input field.

Edge Cases:

  • The component should gracefully handle scenarios where the div might not be immediately available (though for this specific challenge, it will always be rendered in the template).

Examples

Example 1: Basic Interaction

// In the component's template:
<input type="text" [(ngModel)]="userInput">
<div #counterDiv>Type something...</div>

// In the component's TS:
import { Component, viewChild, ElementRef, signal, computed } from '@angular/core';
import { NgModel } from '@angular/forms'; // Assuming ngModel for input binding for simplicity in example

@Component({
  selector: 'app-signal-counter',
  standalone: true,
  imports: [NgModel], // Import if using ngModel
  template: `
    <input type="text" [(ngModel)]="userInput.set">
    <div #counterDiv>{{ displayMessage() }}</div>
  `,
})
export class SignalCounterComponent {
  @viewChild('counterDiv') counterDivRef!: ElementRef<HTMLDivElement>;

  userInput = signal('');

  // This is the part you need to implement using viewChild signal
  // counterDiv = ...;

  displayMessage = computed(() => {
    // This computed property should use the counterDiv signal and userInput signal
    return this.userInput();
  });

  // The actual DOM update will happen implicitly when counterDiv is set up correctly
  // and tied to the displayMessage signal.
}

Explanation:

The user types "Hello" into the input field. The userInput signal updates to "Hello". The displayMessage computed signal reads this value. The challenge is to correctly link the counterDiv viewChild signal so that when displayMessage updates, the counterDiv's content is also updated.

Example 2: Empty Input

Input: User clears the input field.

Output: The div element displays "Type something..." (or the initial default message).

Explanation: When the userInput signal is cleared, the displayMessage computed signal will also reflect an empty string (or potentially the default if handled that way). The viewChild signal mechanism should ensure the div updates accordingly.

Constraints

  • Angular version 16 or higher is required to use Signals.
  • The solution must be implemented in TypeScript.
  • Avoid using setInterval or other imperative DOM manipulation methods outside of the viewChild signal setup.
  • Focus on the declarative approach using Signals.

Notes

  • The viewChild decorator, when used with Signals, returns a signal that resolves to the element reference when it's available.
  • Consider how to combine the viewChild signal with other signals (like the input signal) to drive the DOM updates.
  • Think about the lifecycle of the viewChild signal and when the DOM element becomes accessible.
  • The ElementRef will be the type of the signal's value. You'll need to access its nativeElement to manipulate the DOM.
Loading editor...
typescript