Angular Signals: Implementing a Basic Effect
This challenge focuses on understanding and implementing the effect function from Angular Signals. Effects are a powerful way to react to changes in signal values, enabling declarative side effects within your Angular applications, such as updating the DOM, logging, or making API calls.
Problem Description
Your task is to create a custom Angular directive that utilizes effect to log a message to the console whenever a specific input property of the directive changes. This will demonstrate a fundamental use case for Angular Signals' effect function.
What needs to be achieved:
You need to create an Angular directive named LogChangeEffectDirective. This directive should accept a string input property, let's call it logChangeMessage. Whenever the value of logChangeMessage changes, the directive should log a specific message to the browser's developer console.
Key requirements:
- Create an Angular directive using the
@Directivedecorator. - The directive should be self-contained and not require any specific parent component structure beyond what's needed to apply the directive.
- The directive should define an
@Input()property namedlogChangeMessage. This input will be of typestring. - Use the
effectfunction from@angular/coreto observe changes to thelogChangeMessageinput. - Inside the
effect, log a message to the console in the format:"LogChangeEffect: [current value of logChangeMessage]". - The effect should only trigger when the
logChangeMessagevalue actually changes. - Ensure the directive correctly handles initial setting of the input.
- The effect should be properly cleaned up when the directive is destroyed.
Expected behavior:
- When an element with
LogChangeEffectDirectiveand a[logChangeMessage]binding is initialized, the effect should run and log the initial message. - If the
[logChangeMessage]binding is updated to a new value, the effect should re-run and log the new message. - If the
[logChangeMessage]binding is updated to the same value it already holds, the effect should not re-run.
Important edge cases to consider:
- The initial value of the input.
- Updating the input to
nullorundefined.
Examples
Example 1:
<div appLogChangeEffect [logChangeMessage]="'Initial Value'"></div>
Console Output:
LogChangeEffect: Initial Value
Explanation: When the component renders and the directive is applied, the logChangeMessage input is set to "Initial Value". The effect runs for the first time and logs this message.
Example 2:
<div appLogChangeEffect [logChangeMessage]="dynamicMessage"></div>
TypeScript (Component):
import { Component } from '@angular/core';
@Component({
selector: 'app-my-component',
template: `
<button (click)="changeMessage()">Change Message</button>
<div appLogChangeEffect [logChangeMessage]="dynamicMessage"></div>
`,
})
export class MyComponent {
dynamicMessage: string = 'First Message';
changeMessage() {
this.dynamicMessage = 'Second Message';
}
}
Console Output (after clicking the button):
LogChangeEffect: First Message
LogChangeEffect: Second Message
Explanation: Initially, dynamicMessage is "First Message", and the effect logs it. When the button is clicked, dynamicMessage is updated to "Second Message". The effect detects this change and logs the new message.
Example 3:
<div appLogChangeEffect [logChangeMessage]="'Same Value'"></div>
<div appLogChangeEffect [logChangeMessage]="'Same Value'"></div>
Console Output:
LogChangeEffect: Same Value
LogChangeEffect: Same Value
Explanation: Even though the directive is applied twice with the same message, each directive instance has its own independent effect. Both effects run once for their initial value. If the value were to change later, each effect would react independently.
Constraints
- Angular version: 16+ (required for Signals)
- Input
logChangeMessagewill always be astring,null, orundefined. - The effect should not cause excessive re-renders or performance degradation for simple string changes.
Notes
- Remember to import
effectandInputfrom@angular/core. - Consider the lifecycle of the directive. When should the effect be set up and when should it be cleaned up?
- The
effectfunction takes a callback as its first argument. This callback will be executed whenever any signal read within it changes. - Angular's signal-based
@Input()properties are reactive by default. - The
effectfunction returns a function that can be called to manually destroy the effect and clean up its subscription.