Dev Notes Blog

NgRx Signal Store | Custom Store Features

20th October 2024
NgRx
angular
ngrx
Last updated:6th September 2025
2 Minutes
383 Words

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.

user-preferences.feature.ts
1
import { computed } from '@angular/core';
2
import { signalStoreFeature, withState, withComputed } from '@ngrx/signals';
3
4
export type PreferencesState = {
5
theme: 'light' | 'dark';
6
language: string;
7
notificationsEnabled: boolean;
8
};
9
10
export 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

preference.store.ts
1
export 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.

filter.feature.ts
1
import { computed } from '@angular/core';
2
import { signalStoreFeature, type, withComputed, withState } from '@ngrx/signals';
3
4
export type FilterState = { searchTerm: string };
5
6
export 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

users.store.ts
1
export 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.

Article title:NgRx Signal Store | Custom Store Features
Article author:Andrés Arias
Release time:20th October 2024