Dynamic Filtering with Angular’s linkedSignal v19

Exploring Angular’s linkedSignal: Enhancing Signal Reusability

In Angular applications, managing state and reactivity often involves tools like BehaviorSubject from RxJS. With the advent of signals, particularly linkedSignal, Angular provides a declarative and more Angular-native approach to handling dynamic state transformations.

Let’s build a product filtering example to see how linkedSignal can simplify state management and potentially replace BehaviorSubject.

In this post, we’ll explore what linkedSignal is, its benefits, how it can replace BehaviorSubject in many use cases, and how you can implement it in your Angular applications.


What is linkedSignal?

The linkedSignal function allows you to create a signal whose value is derived from other existing signals. Unlike computed signals that focus on recalculating values reactively, linkedSignal is more tailored for situations where the new signal’s lifecycle and reactivity are closely tied to another signal or context.

This makes linkedSignal a perfect choice when:

  • You need to extend or transform the behavior of an existing signal.
  • You want to maintain a scoped reactive context within your application.

Why Replace BehaviorSubject with Signals?

Traditionally, Angular developers have relied on BehaviorSubject from RxJS for state management, such as holding and propagating reactive data. While powerful, BehaviorSubject has limitations that linkedSignal can address:

1. Boilerplate Reduction

With BehaviorSubject, you often have to write additional boilerplate for initialization, subscriptions, and updates:

const subject = new BehaviorSubject<number>(0);
subject.next(5);
subject.subscribe(value => console.log(value));

In contrast, linkedSignal provides a more concise and declarative API:

const baseSignal = signal(0);
const linked = linkedSignal(() => baseSignal() * 2);
console.log(linked());

2. Declarative State Management

linkedSignal eliminates the need for manual subscription management, reducing the risk of memory leaks and simplifying code structure. It’s purely declarative, meaning dependencies and updates are handled automatically.

3. Tight Integration with Angular

Unlike BehaviorSubject, which is an external library feature, linkedSignal is natively supported in Angular, ensuring seamless integration with other Angular features like templates and change detection.

Scenario: Product Filtering

Imagine you have a list of products, and the user can filter them by category. Using linkedSignal, we can create a reactive filtered list that updates automatically whenever the category or product list changes.

import { Component, signal, linkedSignal } from '@angular/core';

@Component({
  selector: 'app-product-filter',
  standalone: true,
  template: `
    <h2>Product Filter</h2>
    <div>
      <label>Filter by Category:</label>
      <select [value]="selectedCategory()" (change)="selectCategory($event.target.value)">
        <option value="all">All</option>
        <option *ngFor="let category of categories" [value]="category">
          {{ category }}
        </option>
      </select>
    </div>

    <div>
      <h3>Products</h3>
      <ul>
        <li *ngFor="let product of filteredProducts()">
          {{ product.name }} - {{ product.category }}
        </li>
      </ul>
    </div>
  `,
})
export class ProductFilterComponent {
  // Base signal for the list of products
  products = signal([
    { name: 'Laptop', category: 'Electronics' },
    { name: 'Headphones', category: 'Electronics' },
    { name: 'Sofa', category: 'Furniture' },
    { name: 'Table', category: 'Furniture' },
    { name: 'T-shirt', category: 'Clothing' },
  ]);

  // Signal for selected category
  selectedCategory = signal<string>('all');

  // Derived signal for filtering products based on the selected category
  filteredProducts = linkedSignal(() => {
    const category = this.selectedCategory();
    const allProducts = this.products();
    return category === 'all'
      ? allProducts
      : allProducts.filter(product => product.category === category);
  });

  // Generate a list of unique categories from the products
  get categories() {
    return Array.from(new Set(this.products().map(product => product.category)));
  }

  // Update the selected category
  selectCategory(category: string) {
    this.selectedCategory.set(category);
  }
}


Component Code


https://stackblitz.com/~/github.com/kategable/stackblitz-starters-linkedSignal?file=src/app/demo/demo.component.ts

How It Works

  1. Signal Initialization:
    • products contains a static list of products.
    • selectedCategory holds the currently selected category.
  2. Linked Signal:
    • filteredProducts derives its value based on products and selectedCategory. It automatically recalculates when either signal changes.
  3. Reactivity in Action:
    • When the user selects a category, the filteredProducts signal updates the displayed list of products dynamically.
  4. If we used BehaviorSubject:
    • Set up a subject,
    • add pipe for transformations,
    • add manual subscriptions or async pipe.
  5. With linkedSignal:
    • Avoid subscriptions entirely.
    • Use Angular’s built-in reactivity for value updates.
    • Keep the code cleaner and more concise.

Benefits of This Approach

  1. Dynamic Updates: Any change in the product list or selected category immediately updates the filtered list.
  2. Code Clarity: The filtering logic is encapsulated within the linkedSignal, making it reusable and easier to test.
  3. Performance: Signals ensure efficient updates with minimal recalculations.

When to Use linkedSignal Instead of BehaviorSubject

Consider using linkedSignal when:

  • You are managing state within Angular components or services.
  • You want a simpler, Angular-native alternative to RxJS subjects.
  • The logic requires automatic dependency tracking and updates.

However, if you’re managing streams from external sources (e.g., WebSocket connections or complex asynchronous workflows), BehaviorSubject or other RxJS operators may still be more appropriate.

Conclusion

Angular’s linkedSignal simplifies state management by allowing you to derive signals dynamically. This product filter example demonstrates how you can build responsive and dynamic applications with ease.

Give it a try in your next Angular project, and let me know if you want more examples or use cases!

Code link:

git clone https://github.com/kategable/stackblitz-starters-linkedSignal.git

stackblitz – https://stackblitz.com/~/github.com/kategable/stackblitz-starters-linkedSignal?file=src/app/demo/demo.component.ts

get more Angularv19 here https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Leave a Comment