1
votes

I am working on a sample Angular 2 application , and using ngrx/store , ngrx/effects for state management.

Below image depicts one of the screens of my application.

enter image description here

In order to display books list , categories and authors from the server, below dispatch calls are made to the store.

this.store.dispatch(loadCatgories());
this.store.dispatch(loadAuthors());       
this.store.dispatch(loadBooks());

And below the are the related effects

@Effect() authors$ = this.actions$
    .ofType(AuthorActionTypes.LOAD_AUTHORS)
    .switchMap(() => this.authorService.loadAuthors())
    .map(authors => loadAuthorsSuccess(authors));

@Effect() categories$ = this.actions$
    .ofType(CategoryActionTypes.LOAD_CATEGORIES)
    .switchMap(() => this.service.loadCategories())
    .map(categories => loadCategoriesSuccess(categories));      

 @Effect() books$ = this.actions$
    .ofType(BookActionTypes.LOAD_BOOKS)
    .switchMap(() => this.bookService.loadBooks())
    .map(books => loadBooksSuccess(books));     

My questions are

  1. Is the above approach correct or is there any better way , for some reason some times books list is displayed for second and then they disappear.

  2. If my understanding is correct , the above three dispatches are happening parallel, what if I need them to happen one after another.

2
1. The code you posted looks good so far - maybe there is an issue in your reducer or one of the select-calls. - 2. Why is it important to make those calls one after another? The rest-calls don't seem to depend on each other. - olsn

2 Answers

2
votes

 Why isn't it a good idea to load those items separately ?

  • Multiple HTTP requests will slow your app

    • On poor networks this might take a long time
    • Triggers a change detection every time you receive a response (at least 3 times instead of 1)
  • If you want to compose your data, for example with selectors, you might end up with store inconsistency and you don't want that to happen


What should you do instead ?

Do only one request (I suppose you're the one designing the backend too). You might just return something like that :

{
  authors: ...,
  categories: ...,
  books: ...
}

Then you have two options : Dispatch one success action that you'll handle in your 3 reducers separately, or use a lib like redux-batched-actions and do the following : batchActions([ loadAuthorsSuccess(res.authors), loadCategoriesSuccess(res.categories), loadBooksSuccess(res.books) ])

This way, your store will be consistent as only one dispatch will happen.

If you don't have the possibility to modify the backend, use forkJoin to launch the requests at the same time and wait for the 3 requests to end before dispatching (once).

EDIT :
Useful links :
- https://www.youtube.com/watch?v=mhA7zZ23Odw
- http://onehungrymind.com/handle-multiple-angular-2-models-ngrx-computed-observables/ - https://github.com/btroncone/ngrx-examples - http://onehungrymind.com/build-better-angular-2-application-redux-ngrx/

I do love this one http://bodiddlie.github.io/ng-2-toh-with-ngrx-suite/

Once you have a better understanding of ngrx/store & ngrx/effects, you can also take a look into this repo : https://github.com/teropa/harmonics-explorer

0
votes

meanwhile there is ngrx-batch-action-reducer. You can define a "batch action" like "LoadBookList" and can define multiple actions with it.