Sitemap

Angular signals(๐Ÿš€๐Ÿš€)

4 min readJun 10, 2026

--

for years, Angular relied on Zone.js to handle change detection. While it worked behind the scenes to keep the UI in sync with the data, it often felt like a blunt instrument โ€” checking the entire component tree for changes whenever any asynchronous event occurred.

Get Mohamed Aymanโ€™s stories inย yourย inbox

Join Medium for free to get updates fromย thisย writer.

Angular Signals represent a paradigm shift in how the framework manages state and triggers UI updates. Introduced as a developer preview in Angular 16 and fully stabilized in subsequent releases, Signals bring fine-grained reactivity to the ecosystem. Instead of guessing what changed, Angular now knows exactly which piece of data mutated and precisely which part of the DOM needs an update.

What is a Signal?

At its core, a Signal is a wrapper around a value that notifies interested consumers whenever that value changes. Think of it as a value with a built-in megaphone.Signals are synchronous, deterministic, and always possess an initial value. Because they track where they are read, they establish a dependency graph automatically.

The Three Pillars of Signals

Angularโ€™s reactivity model relies on three fundamental building blocks:

  1. Writable Signals: Signals that can be directly updated.
  2. Computed Signals: Read-only signals that derive their value from other signals.
  3. Effects: Operations that run automatically whenever the signals they read change.

Deep Dive into the Core Pillars

Writable Signals

Writable signals allow you to read and write values directly. You initialize them using the signal() function and update them using .set() or .update().

  • Reading a signal: You invoke it like a function: mySignal().
  • .set(): Replaces the value entirely.
  • .update(): Computes a new value based on the current value.

In first image, we see the component's state variables being initialized. It mixes traditional primitive properties with Angular's newer reactive paradigm:

  • Line 1โ€“4: Standard TypeScript properties (value, rating, review) are declared, allowing for direct mutations.
  • Line 5: A Writable Signal named products is initialized using signal<IProduct null |>(null).
  • By using a Signal, Angular sets up an explicit, fine-grained dependency graph for the product data. Whenever this specific data changes, any template or computed function bound to it will be notified automatically without requiring a full component tree re-render.
Press enter or click to view image in full size

2. Fetching and Updating Data (code2.png)

The second image file demonstrates how the component handles asynchronous router streams and updates the declared states inside the ngOnInit lifecycle hook:

  • Route Subscription (Lines 2โ€“5): The code subscribes to Angularโ€™s route.paramMap to grab the current product id from the URL.
  • API Execution & State Mutation (Lines 7โ€“12): Once it receives an ID, it calls an API service (this.api.show<IProduct>) to fetch the product details.
  • The Crucial Distinction: Notice the two different styles of updating state inside the next block:
  • On Line 9, the Signal is updated using its reactive setter method: this.products.set(data).
  • On Lines 10โ€“11, the traditional properties are updated via standard assignment: this.value = data.averageStars.
Press enter or click to view image in full size

3. Declarative UI Binding (code4.jpg)

The third image file displays the HTML template (written with Tailwind CSS utility classes and PrimeNG components like <p-rating> and <p-button>), where the magic of Signals shines in the DOM.

  • Reading the Signal: Because products is a Signal, it must be read by invoking it like a function: products(). We see this clean syntax scattered throughout the template (e.g., products()?.photos on line 3, products()?.name on line 7, and products()?.description on line 24).
  • Modern Control Flow: Lines 11โ€“16 utilize Angularโ€™s modern built-in @if / @else syntax to evaluate whether a product rating value exists, displaying the numerical value or fallback text cleanly.
  • Interactivity: On line 29, the template handles user interaction by binding a click event to an action, passing the unwrapped, non-null value of the signal downstream: setBasketValue(products()!).
Press enter or click to view image in full size

The Big Picture

Together, these files show a classic modern Angular workflow. By shifting from standard properties to the products signal in First image, updating it explicitly via .set() in Second image, and invoking it synchronously as products() in Third Image, the application unlocks localized, high-performance UI updates completely independent of heavy, global change detection cycles.

--

--