Search code examples
angulartypescriptngrxngrx-store

Normalising data shape in ngrx data store


I have an application that retrieves tasks associated with a user from Firebase. In the example below, I have retrieved three tasks, but I can't understand why my data shape has come out as below:

enter image description here

I was hoping that it would look like this:

task: [{ ... }, { ... }, { ... }]

Is it possible to flatten my store as above? This is my code as follows. The mapping happens at TaskActions.dataReceived:

import * as TaskActions from './task.actions';
import { Action, createReducer, on } from '@ngrx/store';
import { ITask } from '../../models/task';

export interface State {
  task: ITask | null;
  error: any;
}

const initialState: ITask = null;

export const taskReducer = createReducer(
  initialState,
  on(TaskActions.getData, state => ({ ...state })),
  on(TaskActions.dataReceived, (state, payload) => ({
    ...state,
    tasks: payload.payload ? [ { ...state, ...payload.payload } ] : []
  })),
  on(TaskActions.dataNotReceived, state => ({ ...state })),
  on(TaskActions.signOut, state => ({ ...state })),
  on(TaskActions.signOutSuccess, state => ({ ...state, ...initialState })),
);

export function reducer(state: ITask | undefined, action: Action) {
  return taskReducer(state, action);
}

Solution

  • (state, payload) => ({
        ...state,
        tasks: payload.payload ? [ { ...state, ...payload.payload } ] : []
      })
    

    This is in practice setting the existing state tasks object to a copy of the state and merging the payload.payload object with it.

    Did you mean to just add the payload to the tasks array? If so you should do this

    if (payload.payload) {
       return {
          ...state,
          tasks: [...state.tasks,  payload.payload]
       }
    }
    
    return state