NgRx 22: Resource Extensions and Dynamic Deep Signals for Angular

NgRx 22 adds experimental resource extensions that change Angular's resource behavior, so value() is retained during reloads and no longer throws on errors. It also introduces dynamic deep signals for union types, a SignalStoreFeatureType utility, and ESLint v10 support. Upgrading requires Angular 22 and TypeScript…

Daniel Curtis 3 min readOriginal

NgRx, the reactive state management framework for Angular, has released version 22, shipping utilities for customising Angular's resource API, dynamic deep signals for union types, a new

SignalStore

typing helper and ESLint v10 compatibility.

The main new addition is resource extensions, delivered through a new experimental

@ngrx/signals/resource

entry point. Angular's

resource

and

httpResource

APIs reset

value()

to

undefined

while reloading and throw when read in an error state. Resource extensions wrap an existing resource and patch only those behaviours, while preserving the original resource type.

Four built-in extensions are included, alongside a

provideResourceExtensions

function that registers defaults at application, route or component level. In the original RFC, Marko Stanimirović explained that changing the error behaviour is also a prerequisite for deeper

SignalStore

integration, as "once a resource enters the error state, any subsequent

patchState

call will throw because it reads

value()

internally".

The proposal was well received, with Manfred Steyer replying "Love it!" and suggesting an activation signal, while another commenter asked for parity with SolidJS's

createResource

, such as access to the current value inside the loader.

A community roundup on DEV noted that similar behaviour could be built with Angular's

snapshot()

and extra state logic, but "with Resource Extensions, you stay on the resource itself", keeping the value writable and retaining the more specific

httpResource

type.

TanStack Query for Angular offers similar previous-data retention when query keys change through placeholderData: keepPreviousData. Separately, the community NgRx Toolkit’s withResource has supported non-throwing

undefined value

and

previous value

; error-handling strategies for SignalStore since v20.6.0.

Version 22 also makes deep signals dynamic. Previously, a state slice typed as a union, the natural way to model "not loaded yet", collapsed into a single flat Signal. Now each object literal member gets its own DeepSignal, reachable after narrowing with an in check.

A new

SignalStoreFeatureType

utility extracts the state and members of a feature factory so custom features can reuse them as input types, rather than redeclaring them by hand. Elsewhere,

@ngrx/store-devtools

gains an

actionCreators

option for dispatching from Redux DevTools, and

@ngrx/eslint-plugin

now supports ESLint v10 while dropping ESLint v8 and the legacy .eslintrc format. The documentation site also gains a light theme.

Developers upgrading need Angular 22, TypeScript 6.0 and RxJS ^6.5 or ^7.5, and can run

ng update @ngrx/store@22

, or

ng update @ngrx/signals@22

for SignalStore-only projects. Most breaking changes have automated migrations, detailed in the v22 migration guide and changelog. Teams should also note that Angular 22 changed resource timing, with one developer reporting test failures that were subsequently added to Angular's release notes as a breaking change.

In the Hacker News thread for Angular v22, one user wrote:

NGRX Signals is the new way and its lovely. Instead of having 5 files to get state hooked up, its usually 1 file and all/most functionality is co-located.

Although another observed that:

Modern Angular is MUCH nicer to use than the v2 days (or even the v4 days when I first started working with it). A lot of the required boilerplate is unnecessary nowadays. And even RxJS and NgRX are becoming less and less necessary to use too, which is great.

NgRx is an open-source, community-driven framework for building reactive Angular applications, providing global state management with Store and Effects alongside the signal-based SignalStore. It is sponsored by Nx and CodeRabbit, and its source is available on GitHub.

I

Originally published on

InfoQ

Read original

Keep reading