Search code examples
angularngrx

ngrx ERROR TypeError: action.payload is not iterable


// action

export class LoadHerosGeneral implements Action {
  readonly type = HerosActionTypes.LOAD_HEROS_GENERAL;

  constructor(public payload?: IHero[]) {}
}

//reducer

export function heroGeneral(state = initialStateGneral, action: HerosActions): IHero[] {
  switch (action.type) {
    case HerosActionTypes.LOAD_HEROS_GENERAL:
      console.log(action.payload);
      return [ ...state, ...action.payload ];
    default:
      return state;
  }
}

// effect

getHeros$: Observable<Action> = createEffect(() =>
  this.action$.pipe(
    ofType(HerosAction.HerosActionTypes.LOAD_HEROS_GENERAL),
    switchMap(() =>
      this.herosService.getHeros()
        .pipe(
          map((heroGeneral: IHero[]) =>
            new HerosAction.LoadHerosGeneral(heroGeneral)
          ),
          catchError(() =>
            EMPTY
          )
        )
      )
    ),
  );

// service I wrapped the service // get all heros

  getHeros(): Observable<IHero[]> {
    return this.generalService.get(`/heroes`);
  }

// general service // GET

  get(endpoint, params?, headers?): Observable<any> {
    return this.httpClient.get<any>(this.BASE_API_URL + endpoint, {
      ...headers,
      ...params
    })
    .pipe(
      catchError(this.errorHandle)
    );
  }

// Component

heroGeneral$: Observable<IHero[]>;

  constructor(
    private store: Store<{ heroGeneral: IHero[] }>,
    private herosService: HerosService,
  ) {
    this.heroGeneral$ = store.select('heroGeneral');
  }

  ngOnInit(): void {
    this.getHerosData();
  }

  getHerosData(): any {
     this.store.dispatch(new herosActions.LoadHerosGeneral());
    // this.herosService.getHeros().subscribe(data => console.log(data));
  }

Seems If I directly use service in my component data works However, if I dispatch, console show error that

ERROR TypeError: action.payload is not iterable

The response data should be array

Could any body help me with this bug? Maybe the effect part?

Thanks.


Solution

  • I think you need to specify some lib in tsconfig to support such iterators.

    But you can do a fast fix too, simply turn an empty payload into an empty array.

    return [ ...state, ...(action.payload || []) ];