Skip to main content

Lab 18: Signal Store

πŸ“– Resources​

πŸš€ Starter Code​

step-19-album-wholesale-v21-post-lazy

In this lab, you'll implement centralized state management using NgRx SignalStore. You'll install @ngrx/signals, create a store with state, computed values, and methods using withState/withComputed/withMethods, and manage async operations with rxMethod.

πŸ“ Instructions​

Step 1: Install @ngrx/signals​

npm install @ngrx/signals

Step 2: Create Signal Store​

Create a store with state, computed values, and methods:

import { signalStore, withState, withMethods, withComputed, patchState } from '@ngrx/signals';

interface AlbumState {
albums: Album[];
loading: boolean;
}

export const AlbumStore = signalStore(
{ providedIn: 'root' },

withState<AlbumState>({
albums: [],
loading: false
}),

withComputed(({ albums }) => ({
totalAlbums: computed(() => albums().length)
})),

withMethods((store, http = inject(HttpClient)) => ({
loadAlbums: rxMethod<void>(
pipe(
tap(() => patchState(store, { loading: true })),
switchMap(() => http.get<Album[]>('/api/albums')),
tap(albums => patchState(store, { albums, loading: false }))
)
)
}))
);

Step 3: Use Store in Component​

Inject and use the store:

export class AlbumListComponent implements OnInit {
albumStore = inject(AlbumStore);

ngOnInit() {
this.albumStore.loadAlbums();
}
}

Template:

@if (albumStore.loading()) {
<p>Loading...</p>
}

@for (album of albumStore.albums(); track album.id) {
<app-album-card [album]="album"></app-album-card>
}

Step 4: Update State with patchState​

Use patchState() to update store state:

// Update single property
patchState(store, { loading: true });

// Update multiple properties
patchState(store, { albums: newAlbums, loading: false });

// Use function for complex updates
patchState(store, state => ({
albums: [...state.albums, newAlbum]
}));