简体   繁体   中英

Angular ngrx - Update store with an array inside object

I have an effects like this:

loadFolder$ = createEffect(() => {
return this.action$.pipe(
  ofType(SidebarAction.loadFirmSuccess),
  switchMap(action => {
    const foldersList = {};

    if(!action.selectedFirm) {
      action.firms[0].roles.map((role: string) => {
        foldersList[role.toLowerCase()] = this.sidebarService.getFolders(action.userId, action.firms[0].id.toString() , role, action.page.toString(), action.size.toString());
      });
    }

    else {
      action.selectedFirm.roles.map((role: string) => {
        // tslint:disable-next-line: no-non-null-assertion
        foldersList[role.toLowerCase()] = this.sidebarService.getFolders(action.userId, action.selectedFirm!.id.toString() , role, action.page.toString(), action.size.toString());
      });
    }

    return forkJoin(foldersList).pipe(map(res => {
      return SidebarAction.loadFolderSuccess({folders : res, selectedFirm: action.selectedFirm});
    }));
  })
);
});

it returns me folders object that is like this

 folders: {
    admin: [[{idFolder: 1, folderName: 'folder1'}], {page: 1, size: 2}, {amount: 3}],
    superadmin: [[{idFolder: 1, folderName: 'folder1'}], {page: 1, size: 2}, {amount: 3}],
    user: [[{idFolder: 1, folderName: 'folder1'}], {page: 1, size: 2}, {amount: 3}]
 }

all the keys are not ever present...it depends.

This is the issue, I have a first result like this:

 folders: {
    admin: [[{idFolder: 1, folderName: 'folder1'}, {idFolder: 2, folderName: 'folder2'}], {page: 1, size: 2}, {amount: 4}]
 }
 

When I increment page I dispatch the same action for having other results

  folders: {
    admin: [[{idFolder: 3, folderName: 'folder3'}, {idFolder: 4, folderName: 'folder4'}]{page: 2, size: 2}{amount: 4}]
 }

This is the reducer:

  export const sideBarReducer = createReducer(
   initialSidebarState,
   on(SidebarActions.loadFolderSuccess, (state, action): SidebarState => {
      return {
               ...state,
               folders: action.folders,
               selectedFirm : action.selectedFirm
      };
    }),
  );

action.folders is potentially an object like this

 folders: {
    admin: [[{idFolder: 1, folderName: 'folder1'}],{page: 1, size: 2},{amount: 3}],
    superadmin: [[{idFolder: 1, folderName: 'folder1'}],{page: 1, size: 2},{amount: 3}],
    user: [[{idFolder: 1, folderName: 'folder1'}],{page: 1, size: 2},{amount: 3}]
 }

I want to update the status for obtaining the previous state with new ones, like this:

  folders: {
    admin: [[{idFolder: 1, folderName: 'folder1'}, {idFolder: 2, folderName: 'folder2'}, {idFolder: 3, folderName: 'folder3'}, {idFolder: 4, folderName: 'folder4'}],{page: 2, size: 2},{amount: 3}],
    superadmin: [[{idFolder: 1, folderName: 'folder1'}],{page: 1, size: 2},{amount: 3}],
    user: [[{idFolder: 1, folderName: 'folder1'}],{page: 1, size: 2},{amount: 3}]
 }

but with reducer I see this state:

     folders: {
       admin: [[{idFolder: 3, folderName: 'folder3'}, {idFolder: 4, folderName: 'folder4'}],{page: 2, size: 2},{amount: 3}],
  
     }

I tried to use spread operator in reducer but it doesn't work. It's obvious because change is inside the array that's into the folder object.

  export const sideBarReducer = createReducer(
   initialSidebarState,
   on(SidebarActions.loadFolderSuccess, (state, action): SidebarState => {
      return {
               ...state,
               folders: {...state.folders, action.folders},
               selectedFirm : action.selectedFirm
      };
    }),
  );

Object spread only do a shallow merge. You need to do deep merging, for example you can use merge

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM