How to fix: 'TypeError: entities not iterable' in ngRx? I am new in using ngrx functionality just referring this URL - https://www.youtube.com/watch?v=igc5rBN50wk&list=PLaMbwDs23r4KXoMucJEyUAvamQ-kFNBvC&index=7
user.effects.ts
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { map, mergeMap, catchError } from 'rxjs/operators';
import { of } from 'rxjs';
import { UserActionTypes, LoadUserAction, LoadUserSuccessAction, LoadUserFailureAction, UpdateUserAction,
UpdateUserSuccessAction, UpdateUserFailureAction, DeleteUserAction, DeleteUserSuccessAction,
DeleteUserFailureAction} from '../actions/user.actions';
import { UserService } from 'src/app/core/services/user.service';
import { UserGraphqlService } from 'src/app/core/services/user-graphql.service';
import { User } from 'src/app/shared/models/user.model';
// Effects perform operation base on any action called by components or services
@Injectable()
export class UserEffects {
constructor(private actions$: Actions,
private userService: UserService,
private userGraphqlService: UserGraphqlService) { }
@Effect()
loadUser$ = this.actions$.pipe(
ofType<LoadUserAction>(UserActionTypes.LOAD_USER),
mergeMap(() => this.userService.sendUserQueryRequest(this.userGraphqlService.getUserListGraphqlString()).pipe(
map((data: User[]) => {
return new LoadUserSuccessAction(data);
}),
catchError(error => of(new LoadUserFailureAction(error)))
))
);
}
problem is in load user listing user.reducers.ts
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { User } from 'src/app/shared/models/user.model';
import { UserAction, UserActionTypes } from '../actions/user.actions';
import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';
export interface UserState extends EntityState<User> {
selectedCustomerId: number | null;
loading: boolean;
error: Error;
}
export const userAdapter: EntityAdapter<User> = createEntityAdapter<User>();
export const defaultUser: UserState = {
ids: [],
entities: {},
selectedCustomerId: null,
loading: false,
error: undefined
};
// Define intialstate value of app state
export const initialState = userAdapter.getInitialState(defaultUser);
// Change store app state as per actions
export function UserReducer(state: UserState = initialState, action: UserAction) {
switch (action.type) {
case UserActionTypes.LOAD_USER:
return {
...state,
loading: true
};
case UserActionTypes.LOAD_USER_SUCCESS:
return userAdapter.addAll(action.payload, {
...state,
// list: action.payload,
loading: false
});
case UserActionTypes.LOAD_USER_FAILURE:
return {
...state,
entities: {},
error: action.payload,
loading: false
};
case UserActionTypes.UPDATE_USER:
return {
...state,
loading: true
};
case UserActionTypes.UPDATE_USER_SUCCESS:
return {
...state,
entities: {},
loading: false
};
case UserActionTypes.UPDATE_USER_FAILURE:
return {
...state,
error: action.payload,
loading: false
};
case UserActionTypes.DELETE_USER:
return {
...state,
loading: true
};
case UserActionTypes.DELETE_USER_SUCCESS:
return {
...state,
entities: {},
// list: {
// ...state.list,
// Users: JSON.parse(JSON.stringify(state.list)).Users.
// filter(item => item.Username !==
// JSON.parse(JSON.stringify(action.payload)).Username)
// },
loading: false
};
case UserActionTypes.DELETE_USER_FAILURE:
return {
...state,
error: action.payload,
loading: false
};
default:
return state;
}
}
const getUserFeatureState = createFeatureSelector<UserState>('user');
// This selector use to fetch all users
export const getUsers = createSelector(
getUserFeatureState,
userAdapter.getSelectors().selectAll,
);
// This selector use to fetch loading value
export const getUsersLoading = createSelector(
getUserFeatureState,
(state: UserState) => state.loading
);
// This selector use to fetch error value
export const getError = createSelector(
getUserFeatureState,
(state: UserState) => state.error
);
// This selector use to fetch specific users base on id
export const getUser = (id: string ) => createSelector(
getUserFeatureState,
userAdapter.getSelectors().selectAll,
// (state: UserState) => {
// const jsonResponse = JSON.parse(JSON.stringify(state.list));
// if (jsonResponse && jsonResponse.Users && jsonResponse.Users.length > 0) {
// const selectedUser = jsonResponse.Users.filter(user => user.Username === id)[0];
// return selectedUser;
// } else {
// return {};
// }
// }
);
user.actions.ts
import { Action } from '@ngrx/store';
import { User } from 'src/app/shared/models/user.model';
// Define all possible action types base on action reducer change state
export enum UserActionTypes {
LOAD_USER = '[User] Load User',
LOAD_USER_SUCCESS = '[User] Load User Success',
LOAD_USER_FAILURE = '[User] Load User Failure',
UPDATE_USER = '[User] Update User',
UPDATE_USER_SUCCESS = '[User] Update User Success',
UPDATE_USER_FAILURE = '[User] Update User Failure',
DELETE_USER = '[User] Delete User',
DELETE_USER_SUCCESS = '[User] Delete User Success',
DELETE_USER_FAILURE = '[User] Delete User Failure',
}
// Use when load all the users
export class LoadUserAction implements Action {
readonly type = UserActionTypes.LOAD_USER;
}
// Use when getting successful all user data
export class LoadUserSuccessAction implements Action {
readonly type = UserActionTypes.LOAD_USER_SUCCESS;
constructor(public payload: Array<User>) { }
}
// Use when getting an error while loading user data
export class LoadUserFailureAction implements Action {
readonly type = UserActionTypes.LOAD_USER_FAILURE;
constructor(public payload: Error) { }
}
// Update User
export class UpdateUserAction implements Action {
readonly type = UserActionTypes.UPDATE_USER;
constructor(public payload: User) { }
}
// Update User Success
export class UpdateUserSuccessAction implements Action {
readonly type = UserActionTypes.UPDATE_USER_SUCCESS;
constructor(public payload: User) { }
}
// Update User Failure
export class UpdateUserFailureAction implements Action {
readonly type = UserActionTypes.UPDATE_USER_FAILURE;
constructor(public payload: Error) { }
}
// Delete User
export class DeleteUserAction implements Action {
readonly type = UserActionTypes.DELETE_USER;
constructor(public payload: User) { }
}
// Delete User Success
export class DeleteUserSuccessAction implements Action {
readonly type = UserActionTypes.DELETE_USER_SUCCESS;
constructor(public payload: User) { }
}
// Delete User Failure
export class DeleteUserFailureAction implements Action {
readonly type = UserActionTypes.DELETE_USER_FAILURE;
constructor(public payload: Error) { }
}
export type UserAction = LoadUserAction | LoadUserSuccessAction |
LoadUserFailureAction | UpdateUserAction | UpdateUserSuccessAction | UpdateUserFailureAction |
DeleteUserAction | DeleteUserSuccessAction | DeleteUserFailureAction;
user.graphql.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class UserGraphqlService {
getUserListGraphqlString() {
return `query {
listUsers {
Users {
Attributes {
Name,
Value
},
UserCreateDate,
UserLastModifiedDate,
Username,
UserStatus,
Group,
Enabled
},
user_pool_id,
user_name,
group_name,
message,
result
}
}`;
}
}
where, user.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { map, mergeMap, catchError } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
// Use to fetch data from the server
export class UserService {
private URL = '';
constructor(private http: HttpClient) {
this.URL = environment.URL;
}
sendUserQueryRequest(data) {
return this.http.post<any>(this.URL + '/query', data).pipe(map(val => val.data.listUsers));
}
deleteUserQueryRequest(data) {
return this.http.post<any>(this.URL + '/query', data).pipe(map(val => val.data.deleteUser));
}
}
getting an error
core.js:6014 ERROR TypeError: entities is not iterable
at addManyMutably (http://localhost:4200/users-users-module.js:214:30)
at setAllMutably (http://localhost:4200/users-users-module.js:227:9)
at Object.operation [as addAll] (http://localhost:4200/users-users-module.js:149:27)
at UserReducer (http://localhost:4200/users-users-module.js:3033:32)
at http://localhost:4200/vendor.js:267485:20
at combination (http://localhost:4200/vendor.js:267373:37)
at http://localhost:4200/vendor.js:268249:27
at http://localhost:4200/vendor.js:267453:20
at computeNextEntry (http://localhost:4200/vendor.js:266247:21)
at recomputeStates (http://localhost:4200/vendor.js:266300:15)