Search code examples
angulartypescriptreduxngrx

TypeError: action.payload is not iterable


Hello now I'm studying ngrx, but I have a big problem. I don't know how to fix it. someone who can help me plz... I got TypeError: action.payload is not iterable error. if I change [...action.payload] to just action.payload in reducer.ts, I can get data but I need to use [...action.payload]. what is problem? thank you

images.reducer.ts

import { Image } from "../../../Image/models/image.model";

import * as ImagesActions from "./images.action";

export interface State {
  images: Image[];
}

const initialState: State = {
  images: [],
};

export function imagesReducer(
  state = initialState,
  action: ImagesActions.ImagesActions
) {
  switch (action.type) {
    case ImagesActions.GET_IMAGES:
      console.log(state.images);
      console.log("get images reducer ", action.payload);

      return {
        ...state,
        images: [...action.payload],
      };
    default:
      return state;
  }
}

images.effect.ts

fetchImages$ = createEffect(
    () => {
      console.log("fetch images effect ");

      return this.actions$.pipe(
        ofType(ImagesActions.FETCH_IMAGES),
        map((action: ImagesActions.FetchImages) => action.payload),
        switchMap(() => {
          return this.http.post<Image[]>(this.globalUrl + "/admin/image");
        }),
        map((images) => {
          console.log(images);

          //return images.map((image) => {
          return {
            ...images,
            //images: image ? image : [],
          };
          //});
        }),
        map((images) => {
          console.log("fetch images effect images ", images);
          return new ImagesActions.GetImages(images);
        })
      );
    }
  );

images.action.ts


export class GetImages implements Action {
  readonly type = GET_IMAGES;
  constructor(public payload: Image[]) {}
}


app.reducer.ts

import { ActionReducerMap } from "@ngrx/store";

import * as fromUsers from "../admin/users/store/users.reducer";
import * as fromImages from "../admin/image/store/images.reducer";
import * as fromPosts from "../admin/post/store/posts.reducer";

export interface AppState {
  users: fromUsers.State;
  images: fromImages.State;
  posts: fromPosts.State;
}

export const appReducer: ActionReducerMap<AppState> = {
  users: fromUsers.usersReducer,
  images: fromImages.imagesReducer,
  posts: fromPosts.postsReducer,
};


Solution

  • You are creating an object here, not an array.

            switchMap(() => {
              return this.http.post<Image[]>(this.globalUrl + "/admin/image");
            }),
            map((images) => {
              return {
                ...images,
              };
            }),
    

    Example:

    { ...['a', 'b', 'c'] }
    -->
    {0: "a", 1: "b", 2: "c"}