How do I correctly handle updates to the NgRx component store in case I have many Observables triggering updates at the same time and all updates have effects on the same property in the store?
To use the example from the official documentation with storing movies: I have many Observables which can lead to changes regarding which movies to display. Think of it like I had several of the following code snippets in my component:
someMovie.pipe(takeUntil(this.onDestroy$)).subscribe(({movie: IMovie, shouldBeDisplayed: boolean}) => {
this.updateMovieVisibility(movie, shouldBeDisplayed);
});
And the component store's function is implemented like this:
public updateMovieVisibility(movie: IMovie, shouldBeDisplayed: boolean) {
this.patchState((state) => {
let newMoviesToDisplay = [...state.displayedMovies];
if (shouldBeDisplayed) {
newMoviesToDisplay.push(movie);
} else {
newMoviesToDisplay = newMoviesToDisplay.filter((item) => item.id !== movie.id);
}
return {
displayedMovies: newMoviesToDisplay,
};
});
}
Now I am facing a problem when several new movies should be displayed. Their Observables emit "at the same time". According to my debug outputs, the following happens in chronological order.
- [Only movie X is displayed at the beginning]
- The Observable for movie Y emits. Debug outputs show that
state.displayedMoviescontains movie X at the start and thatnewMoviesToDisplaycontains both movies[X, Y]directly before the return statement. - The Observable for movie Z emits. Debug outputs show that
state.displayedMoviescontains only movie X. The state update has not yet been processed and therefore the information is missing that movie Y should be displayed as well. As a result, the patchState update returns only[X, Z]instead of[X, Y, Z]. - Other debug code shows that the changes to the store are emitted. My selector emits first
[X, Y]and then[X, Z].
How do I correctly handle this situation? My second state update does not yet see the changes made by the first update. Is there some mechanism which allows me to wait for all pending state updates before I call the next patchState()?