Search code examples
angularngrx

Angular Ngrx store with multiple Arrays in state


I'm trying to use Ngrx for the first time , I have been following this tutorial https://www.techiediaries.com/angular-10-ngrx-store-example/

my question is can I define my state with something like this:

export interface AppState {
    readonly firstArray: Number[];
    readonly secondArray: Number[];
    readonly thirdArray: Number[];
}

and in that case how should I implement My reducer :

export const UPDATE_DATA = 'TEMP';

export function tempReducer(state: /* How to initialize three empty arrays here ? */, action) {
  switch (action.type) {
    case TEMP:
        /*How to Update arrays here? */
    default:
        return state;
    }
}

Also is it possible to update the whole array inside the state ? (for example assign a new array to firstArray and not only add or remove elements from it)


Solution

  • According to what you have supplied (the tutorial source included), you have a couple of options. You could have 1 reducer for each array, as each array become part of the state (also called a slice) or you could have an object which in turn contains the 3 arrays and then use 1 reducer for that object. For the second option, you will have to manage the state of the 3 arrays (all properties) of the object in the reducer.

    Below are some examples but I made some assumptions so you might have to make some adjustments.

    Option 1: In your root module

    imports: [
        ...
        StoreModule.forRoot({
            firstArray: firstArrayReducer,
            secondArray: secondArrayReducer,
            thirdArray: thirdArrayReducer
        });
    ]
    

    Your reducer code could look like this:

    export const ADD_DATA    = 'ADD';
    export const UPDATE_DATA = 'UPDATE';
    
    export function firstArrayReducer(state: YourFirstArrayType[] = [], action) {
      switch (action.type) {
        case ADD_DATA:
            // This will create a shallow copy of the array and
            // append your latest element to it
            return [...state, action.payload];
        case UPDATE_DATA:
            // Clone your array and return it with the desired modification
            const shallowClone = [...state];
            shallowClone[1] = action.payload; // This is an example
            return shallowClone;
        default:
            return state;
        }
    }
    

    Option 2: Is similar but instead of your state being a simple array, it could be an object that would in turn have the 3 arrays.

    In your root module

    imports: [
        ...
        StoreModule.forRoot({ objOfArrays: objArraysReducer });
    ]
    

    Your reducer code could look like this:

    export const ADD_DATA    = 'ADD';
    export const UPDATE_DATA = 'UPDATE';
    
    export const initialState = {
        firstArray: [],
        secondArray: [],
        thirdArray: []
    };
    
    export function objArraysReducer (state: YourObjectType = initialState, action) 
    {
      // Now you need to find a way to detect what has change and update accordingly
      switch (action.type) {
        case ADD_DATA:
            // Your code...
            return state;
        default:
            return state;
        }
    }
    

    Also is it possible to update the whole array inside the state ? (for example assign a new array to firstArray and not only add or remove elements from it)

    Not only it is possible as it is the desired behavior and a whole principle that NgRx are built upon. Above I used new arrays instead of mutating them.