Search code examples
angularngrxngrx-store

ngrx Reducer to change multiple states


I can't find the way to create a reducer that changes multiple state, the API Rest returns nested data, which I normalize using normalizr library. Here is my code.

Api returns data:

[
  {id: 1, firstName: 'CRISTIAN', lastName: 'QUISPE', country: {id: 1, name: 'PERU'}},
  {id: 2, firstName: 'ISRRAEL', lastName: 'ALCAZAR', country: {id: 10, name: 'ESPAÑA'}}
];

Schema normalizr:

import {schema} from 'normalizr';

export const country = new schema.Entity('countries');
export const person = new schema.Entity('people', {
  country: country
});

Normalized data: enter image description here

State tree expected: enter image description here

Which should be the reducer that receives the data of the api rest and generates the previous state tree.


Solution

  • Once you've got your normalized data, you have 2 solutions :

    1. Dispatch one action (for ex updateCountriesAndPeople) that will be handled by countriesReducer and peopleReducer
    2. Dispatch 2 different actions :
      One for countriesReducer, let's call it updateCountries
      One for peopleReducer, let's call it updatePeople

    The first is pretty straight forward :

    const updateCountriesAndPeople = 'UPDATE_COUNTRIES_AND_PEOPLE';
    
    function countriesReducer(state, action) {
      switch(action.type) {
        case updateCountriesAndPeople: {
          // do what you want with payload.entities.countries
        }
      }
    }
    
    function peopleReducer(state, action) {
      switch(action.type) {
        case updateCountriesAndPeople: {
          // do what you want with payload.entities.people
        }
      }
    }
    

    For the solution n°2, if you dispatch 2 actions, you'll end up in a state inconsistency between the 2 dispatch. And thus, if you want to avoid that you should use a library called redux-batched-actions. It will allow you to dispatch multiple actions at once, and for example if you have some selectors to build your data, they'll be triggered only once.

    Personally, sometimes I like to split my actions if I know I'll possibly want to re-use those small actions independently.

    If you want something really simple, take the solution n°1 :).