1

I've been running through tutorials on NGRX and have tried to implement a UserAdapter with a custom id from MongoDB _id. So I got the whole custom id working but I keep getting this error ERROR TypeError: "ids is undefined" from the select all Adapter. I've so far concluded that it comes from the selectAll selector in the adapter but I don't know what to do to fix it...

So here's my users.reducer.ts

export interface UserState extends EntityState<UserModel> {
  loading?: boolean;
  failed?: Error;
}

export const UserAdapter: EntityAdapter<UserModel> = createEntityAdapter<UserModel>({
  selectId: (user: UserModel) => user._id,
  sortComparer: (a: UserModel, b: UserModel): number => a._id.localeCompare(b._id)
});

const InitialState = UserAdapter.getInitialState({
  loading: false,
  ids: [] // I tried sticking this here but it doesn't help
});


const Reducer = createReducer(
  InitialState,
  on(LoadUsers, (state) => ({
    ...state,
    loading: true
  })),
  on(SuccessUsers, (state, action) => UserAdapter.addMany(action.users, {
    ...state,
    failed: undefined,
    loading: false,
  })),
  on(FailedUsers, (state, action) => ({
    ...state,
    loading: false,
    failed: action,
  })),
);


export function UsersReducer(state, action: Action) {
  return Reducer(state, action);
}

const {
  selectAll,
} = UserAdapter.getSelectors();


export const SelectAllUsers = selectAll;

here's the users.model.ts

export interface UserModel {
  _id: string;
  fullname: string;
  pin: string;
  mobile: string;
  qrcode: string;
  image: string;
  secret: string;
  position: {
    type: string,
    coordinates: number[]
  }[];
  roles: {name: string, user: string}[];
  token: string;
}

and here's my users.action.ts

import {createAction, props} from '@ngrx/store';
import {UserModel} from '../../../../models/user.model';

export enum UsersActionTypes {
  loadusers = '[USERS]: load users',
  successusers = '[USERS]: success users',
  failedusers = '[USERS]: failed users',

  filterusers = '[USERS]: filter users',
  searchusers = '[USERS]: search users'
}

export const LoadUsers = createAction(UsersActionTypes.loadusers);

export const SuccessUsers = createAction(UsersActionTypes.successusers,
  props<{users: Array<UserModel>}>());

export const FailedUsers = createAction(UsersActionTypes.failedusers,
  props<Error>());

export const FilterUsers = createAction(UsersActionTypes.filterusers,
  props<{filter: string, search?: string}>());

export const SearchUsers = createAction(UsersActionTypes.searchusers,
  props<{search: string, filter?: string}>());

here's my component also users.component.ts


@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.scss']
})
export class UsersComponent implements OnInit {
  users: Observable<UserModel[]>;

  @ViewChild('controls') controls: ControlsComponent;

  constructor(private store: Store) { }

  ngOnInit(): void {
    if (this.store) {
      this.users = this.store.select(SelectAllUsers);
      this.users.subscribe((users) => {
        console.log(users);
        if (!users) {
          this.store.dispatch(LoadUsers());
        }
      });
    }
  }

}

Please help, I've tried a bunch of stuff that doesn't work...

bloo
  • 1,416
  • 2
  • 13
  • 19
  • can you add `UserModel` and actions definitions? – cabesuon Jun 19 '20 at 09:44
  • ok ive added it in – bloo Jun 19 '20 at 09:47
  • you are sure that the data that you are receiving is correct?, can you add a log of that?, just to be sure .. if you can, to complete the cycle and the effect and service for load – cabesuon Jun 19 '20 at 13:19
  • 1
    Hey man, I actually figured what my problem was...I was trying to create a feature selector on another feature selector and yet that does not work...so that was why the ids were undefined...because the state was undefined you know...so after creating my selectors properly everything started working nicely – bloo Jun 19 '20 at 13:22
  • Great .. You should add a little answer – cabesuon Jun 19 '20 at 13:27
  • Ok will do, thanks so much for your time ey...I greatly appreciate it...:) – bloo Jun 19 '20 at 13:29

2 Answers2

1

Yes, my selectors were failing as well (specifically select all adapter call). For me, the problem was caused in the module file. I originally registered my reducer like this:

StoreModule.forFeature("courses", [coursesReducer])

and I fixed it by doing this (remove the array)

StoreModule.forFeature("courses", coursesReducer)

The other symptom I was seeing was in the Redux extension tools, which was also fixed when I removed the array above: enter image description here

David Yates
  • 1,935
  • 2
  • 22
  • 38
0

Try to define your ids as empty array in initial state.

ids: [] = [];
emihud
  • 138
  • 8