In Angular, signals are used to manage reactive state by storing a value and automatically updating any dependent components or views when the value changes.
import { WritableSignal, signal } from '@angular/core';export class ExampleComponent {count: WritableSignal<number> = signal(0);increment() {this.count.update(value => value + 1);}}
signal()
FunctionIn Angular, the signal()
function is used to create a signal with an initial value that can be updated and observed reactively.
import { signal, WritableSignal } from '@angular/core';export class ExampleComponent {count: WritableSignal<number> = signal(0);increment() {this.count.update(n => n + 1);}}
In Angular, a signal’s current value can be accessed by calling its getter function ()
.
import { signal, WritableSignal } from '@angular/core';export class ExampleComponent {count: WritableSignal<number> = signal(0);logCurrentValue() {console.log(this.count()); // accessing the current value of count signal}increment() {this.count.update(n => n + 1);}}
set()
FunctionIn Angular, the set()
method directly assigns a new value to a signal, completely replacing the previous value. Unlike update()
, set()
doesn’t provide access to the current value during the assignment.
import { signal, WritableSignal } from '@angular/core';export class ExampleComponent {theme: WritableSignal<string> = signal('light');toggleTheme() {this.theme.set('dark');}reset() {this.theme.set('light');}}
update()
FunctionIn Angular, the update()
method changes a signal’s value by applying a function that uses the current value to calculate a new value. This approach ensures safe access to the current value when calculating the new state.
import { signal, WritableSignal } from '@angular/core';export class ExampleComponent {count: WritableSignal<number> = signal(0);increment() {this.count.update(currentValue => currentValue + 1);}double() {this.count.update(currentValue => currentValue * 2);}}
computed()
FunctionIn Angular, the computed()
function creates a signal that derives its value from other signals, automatically updating whenever its dependencies change. Dependencies are automatically tracked when signals are accessed (using parentheses) within the computed function.
import { signal, computed, WritableSignal, Signal } from '@angular/core';export class ExampleComponent {count: WritableSignal<number> = signal(0);multiplier: WritableSignal<number> = signal(2);result: Signal<number> = computed(() => this.count() * this.multiplier());increment() {this.count.update(n => n + 1);}changeMultiplier() {this.multiplier.update(n => n + 1);}}
effect()
FunctionIn Angular, the effect()
function executes code automatically whenever its signal dependencies change. Effects are used for performing tasks in response to signal changes (like updating the DOM or making API calls) and don’t return values. Like computed signals, they automatically track any signals that are read within their function body.
import { signal, effect, WritableSignal } from '@angular/core';export class ExampleComponent {userName: WritableSignal<string> = signal('Guest');constructor() {effect(() => {document.title = `Welcome, ${this.userName()}`;});}updateName(newName: string) {this.userName.set(newName);}}
untracked()
FunctionIn Angular, the untracked()
function reads a signal’s value without adding it as a dependency in effects or computed signals. This means changes to signals read within untracked()
won’t trigger effects or computed signals to update.
import { signal, effect, untracked, WritableSignal } from '@angular/core';export class ExampleComponent {count: WritableSignal<number> = signal(0);limit: WritableSignal<number> = signal(5);constructor() {effect(() => {// This creates a dependency - effect runs when count changesconsole.log(`Count is: ${this.count()}`);// Using untracked() - effect won't run when limit changesconsole.log(`Limit is: ${untracked(() => this.limit())}`);});}}
In Angular, the input()
function creates signal-based component inputs that update automatically when their values change. These inputs are read-only signals that can be accessed in the component’s template or class using the signal getter syntax.
import { Component, input } from '@angular/core';@Component({selector: 'app-child',template: `<p>Value: {{ value() }}</p>`})export class ChildComponent {value = input<number>();}@Component({selector: 'app-parent',template: `<app-child [value]="10" />`})export class ParentComponent {}
model()
FunctionIn Angular, the model()
function creates a special signal that enables two-way data binding by combining input and output functionality. Changes can flow both from parent to child and from child back to parent.
import { Component, model, ModelSignal } from '@angular/core';// Child component@Component({selector: 'app-child',template: '<button (click)="increment()">Increment</button>'})export class ChildComponent {value = model<number>(0);increment() {this.value.update(val => val + 1);}}// Parent component@Component({selector: 'app-parent',template: '<app-child [(value)]="parentValue()"></app-child>'})export class ParentComponent {parentValue = signal(10);}
viewChild()
FunctionIn Angular, the viewChild()
function creates a signal that references a child element or component using a template reference variable, automatically updating when the referenced element or component changes.
import { Component, viewChild, ElementRef } from '@angular/core';@Component({selector: 'app-parent',template: `<div #myDiv></div>`})export class ParentComponent {myDiv = viewChild<ElementRef>('myDiv');}
contentChild()
FunctionIn Angular, the contentChild()
function creates a signal that references content projected into a component through ng-content
, automatically updating when the projected content changes.
import { Component, contentChild, ElementRef } from '@angular/core';@Component({selector: 'app-container',template: `<ng-content></ng-content>`})export class ContainerComponent {content = contentChild<ElementRef>('projectedContent');}@Component({selector: 'app-parent',template: `<app-container><p #projectedContent>Projected Content</p></app-container>`})export class ParentComponent {}
In Angular, signals and observables serve different purposes in reactive programming. Signals manage a single value that updates synchronously, providing direct access to the current state. Observables, in contrast, manage streams of values over time, with built-in support for asynchronous data flow.
import { Component, signal } from '@angular/core';@Component({selector: 'app-example',template: `<div>Count: {{ count() }}</div><button (click)="increment()">Add</button>`})export class ExampleComponent {// Signal: Always has a current valuecount = signal(0);increment() {this.count.update(n => n + 1);}}