With regard to NgRx v16 new with Angular Signals, given:
export const selectCustomer = (id: string) =>
createSelector(selectCustomers, (customers) => customers[id]);
(common expression; taken from Tim Deschryver's blog-post on how to do this with NgRx, up to v15)
Question 1, how should this be done when I have a Signal<string>
for id
?
FYI, currently I keep the selector as-was and use Angular's toSignal
/toObservable
, which seems like a bad detour:
import { toSignal, toObservable } from '@angular/core/rxjs-interop'
…
let id: Signal<string>;
…
const customer$ = toSignal(toObservable(id).pipe(
switchMap(id => store.select(selectCustomer(id)))
));
Also, toObservable
requires an injection context, so there are limitations where it can be used in the code.
And regarding memoization like
import * as _ from "lodash";
…
export const selectCustomer = _.memoize((id: string) =>
createSelector(selectCustomers, (customers) => customers[id])
);
Question 2, will such manual memoization then become unnecessary?
With set withComponentInputBinding in appConfig I got it to work with using computed.
// books.component.ts
export class BookDetailsComponent {
private store = inject(Store);
id = input<string>();
book = computed(() => this.store.selectSignal(selectBook(this.id()))());
}
// app.config.ts
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(
routes,
withComponentInputBinding() // route id parameter => to id input signal
),
provideStore(reducers, { metaReducers, runtimeChecks }),
provideEffects(effects),
provideHttpClient(),
],
};