Custom SignalStore features provide a strong way to add extra functionality and organize common patterns, making it easier to reuse and share code across different stores. This helps keep your code more organized and reduces repetition in your application.
What Are Custom Features?
A custom feature in SignalStore is a reusable set of state slices, computed signals, or methods that can be applied to multiple stores. By creating custom features, you can keep your codebase DRY (Don’t Repeat Yourself), make state management consistent, and easily add new functionality to your app.
1import { computed } from '@angular/core';2import { signalStoreFeature, withState, withComputed } from '@ngrx/signals';3
4export type PreferencesState = {5 theme: 'light' | 'dark';6 language: string;7 notificationsEnabled: boolean;8};9
10export function withUserPreferences() {11 return signalStoreFeature(12 withState<PreferencesState>({13 theme: 'light',14 language: 'en',15 notificationsEnabled: true,7 collapsed lines
16 }),17 withComputed(({ theme, language, notificationsEnabled }) => ({18 isDarkMode: computed(() => theme() === 'dark'),19 isEnglish: computed(() => language() === 'en'),20 })),21 );22}Using the withUserPreferences
1export const PreferencesStore = signalStore(withUserPreferences());Custom Store Features with Inputs
Custom store features can also accept inputs to become more flexible, allowing them to adapt based on the store they are used in. These inputs can include state, computed signals, or methods that the store provides, making the feature more customizable.
1import { computed } from '@angular/core';2import { signalStoreFeature, type, withComputed, withState } from '@ngrx/signals';3
4export type FilterState = { searchTerm: string };5
6export function withFilter() {7 return signalStoreFeature(8 { state: type<{ items: Entity[] }>() },9 withState<FilterState>({ searchTerm: '' }),10 withComputed(({ items, searchTerm }) => ({11 filteredItems: computed(() => {12 const term = searchTerm().toLowerCase();13 return items().filter((item) => item.name.toLowerCase().includes(term));14 }),15 })),2 collapsed lines
16 );17}The withFilter feature takes the store’s items list as an input and adds the ability to filter these items based on a search term provided by the feature. This makes it a reusable feature for any store managing a collection of items.
Using the withFilter
1export const UsersStore = signalStore(withState({ items: [] }), withFilter());Custom store features can also accept inputs to become more flexible, allowing them to adapt based on the store they are used in. These inputs can include state, computed signals, or methods that the store provides, making the feature more customizable. You can define the expected state slices, methods, or computed signals within the feature itself, ensuring that the store using the feature has the necessary inputs to function correctly.