Search code examples
angularrxjssignalsngrx

Chain rxMethods with NGRX & signals


The Ngrx last update offers support for Angular signals.

I’m looking for a way to chain rxMethods with NGRX & signals.

Firstly I thought of chaining them directly in the store statement.

However I was not able to figure out how this can be done, nor if it’s the right thing to do.

I would be grateful if someone knows how to perform such synchronous calls.

export const BookStore = signalStore(
    {providedIn: 'root'},
    withState(initialState),
    withMethods((store, bookService = inject(BookService)) => ({
        loadRandomAuthor: rxMethod<number>(
            pipe(
                switchMap(() => {
                    return bookService.getRandomAuthor().pipe(
                        tap({
                            next: (author: Author) => {
                                patchState(store, {author});
                                // 👉 call loadBooksByAuthorId method with author.id here
                            },
                        })
                    );
                })
            )
        ),
        // 👉 here is the method to be synchronously called
        loadBooksByAuthorId: rxMethod<number>(
            pipe(
                switchMap((authorId: number) => {
                    return bookService.getBooksByAuthorId(authorId).pipe(
                        tap({
                            next: (books: Book[]) => {
                                patchState(store, {books});
                            },
                        })
                    );
                })
            )
        )
    }))
);

Solution

  • HTTP requests are asynchronous. What you meant is consequent.

    Calling one effect from another is a code smell.

    I recommend this way: loadRandomAuthor() should set authorId in the state, and loadBooksByAuthorId() should observe authorId in the state and load books when that id is changed.

    Your loadRandomAuthor() already sets author, so loadBooksByAuthorId() should observe state.author.id.