NgRx v22 ·
NgRx v22: keep a paged list on screen while the next page loads
NgRx v22's withPreviousValueOnLoading keeps a resource's last value while new data loads, so paged lists stop flashing empty. How it works, and one open bug.
Change the page or the filter on a list that comes from an Angular resource, and the list goes empty until the new data arrives. NgRx v22 adds withPreviousValueOnLoading(), which keeps the old rows on screen in the meantime. It lives in @ngrx/signals/resource, is marked experimental, and shipped in NgRx 22.0.0 on 24 August.
Why the list goes empty
When a resource's params change, Angular sets its status to 'loading' and value() falls back to the default value, which is undefined unless you set defaultValue. A reload() with the same params is different: the status is 'reloading' and Angular already keeps the previous value. So the flash shows up when you page or filter, not when you refresh.
Using it
extendResource takes any resource, including httpResource and rxResource, applies the extensions and returns the same object with the same type:
import { signal } from '@angular/core';
import { httpResource } from '@angular/common/http';
import { extendResource, withPreviousValueOnLoading } from '@ngrx/signals/resource';
export class Orders {
page = signal(1);
orders = extendResource(
httpResource<Order[]>(() => `/api/orders?page=${this.page()}`),
withPreviousValueOnLoading(),
);
}While the next page loads, orders.value() returns the last rows, status() still says 'loading' and isLoading() stays true, so you can still dim the list or show a spinner. On the very first load there is nothing to keep, and value() is undefined. Errors are not hidden: in the 'error' state value() still throws, and NgRx has withPreviousValueOnError() and withValueOnError() for that case.
extendResource calls inject(), so create the resource in a field initializer or another injection context. To apply the extension to every extendResource call, register it once with provideResourceExtensions(withPreviousValueOnLoading()).
One open bug
In NgRx 22.0.1, the latest release, a computed that first reads value() while the resource is loading can stay stuck on the old value (issue #5224). During loading the cached value comes back without reading a signal, so the computed records no dependency. The workaround in the issue is to also read isLoading() inside the computed. A fix has been approved but is not released yet.
Being experimental, the API may change without the usual breaking-change notice. For paged and filtered lists I'd still use it, with that bug in mind for derived values.
Sources
- Announcing NgRx v22 (NgRx team)
- Resource extensions guide (ngrx.io)
- withPreviousValueOnLoading API reference
- NgRx issue #5224: computed value stays stale
I post short notes like this on LinkedIn.
Need help with this?
