Angular Signals 🔊

J. R. Smith
2 min readJan 23, 2024

--

Astronomy deep space radio telescope arrays at night pointing into space

What are Angular Signals?

// Like variables, a signal holds a value that can change
const example = signal("value");

// Unlike variables, signals tell Angular when they change
example.set("new value");

// Angular will re-render that component when the value of a signal changes
<>
<p> {{ example() }} </p>
</>

At a glance

  • Signals are ‘reactive primitives’, which are used to tell the framework what data your UI cares about; so when that data changes, the UI is kept in sync
  • Signals know where across your app they are used and notify these components when the value inside has changed
  • There are 3 types of signals: writable, computed and effects

What we did before Angular Signals

  • Signals were introduced as developer preview in v16
  • Before this we had two options:
// #1 - Simple variable reference
value = 1;

<h1> {{ value }} </h1>


// #2 - Behaviour Subject (rxjs)
value = new BehaviorSubject<number>(1);

<h1> {{ value | async }} </h1>

Illustrative Performance Comparison

Without using signals, the whole component tree is re-rendered after change detection occurs.
With ChangeDetectionStrategy.OnPush, the whole component branch above our change is re-rendered
With signals, only the component that uses the signal is re-rendered

How do we use them?

  • Writable: “Its value is updated directly”
  • Computed: “Derives it’s value from another signal”
  • Effects: “An operation that runs whenever one or more signals change”
// my.component.ts
...

@Component({
selector: 'my',
standalone: true,
imports: [...],
templateUrl: './my.component.html',
styleUrl: './my.component.scss'
})
export class MyComponent implements OnInit {

// Signal :: Writable
mileage: WritableSignal<number> = signal(0);

// Signal :: Computed
kilometrage: Signal<number> = computed(() => 1.60934 * this.mileage());

// Signal :: Effect
effect(() => {
console.log(`The current mileage is: ${mileage()}`);
});

increaseVolume(): void {
this.mileage.update((value) => value++);
}

}
<!-- my.component.html -->

<h1> Miles : {{ mileage() }} </h1>

<h1> Kilometeres: {{ kilometrage() }} </h1>

<button (click)="increaseVolume()">Increase Volume</button>

Further Reading

--

--

No responses yet