ceno980
ceno980

Reputation: 2011

React-Redux - TypeError: state.menu is not iterable

I am working on a React application and I am using Redux to store the state. I have the following code:

menu.reducer.js:

import { INCREASE_CATEGORY_RANK, DECREASE_CATEGORY_RANK } from './menu.types';

const INITIAL_STATE = []


export default (state = INITIAL_STATE, action) => {
    switch (action.type) {

        case INCREASE_CATEGORY_RANK: { 
            console.log("Printing state");
            console.log(state);
            const menuArray = [...state.menu];
            menuArray.sort((a,b) => (a.rank > b.rank) ? 1 : -1);
            return {
               ...state,
               menu: menuArray
            }
        }
        case DECREASE_CATEGORY_RANK: {
            return state.map(category => {
                if (category._id === action.payload._id && category.rank !== -1) {
                    const oldrank = category.rank;
                    return {
                        ...category,
                        rank: oldrank - 1
                    }
                } else {
                    return category;
                }
            })
        }
        default:
            return state;
    }
}

menu.types.js:

export const INCREASE_CATEGORY_RANK = "INCREASE_CATEGORY_RANK";
export const DECREASE_CATEGORY_RANK = "DECREASE_CATEGORY_RANK";

menu.actions.js:

import { apiUrl, apiConfig } from '../../util/api';
import { INCREASE_CATEGORY_RANK, DECREASE_CATEGORY_RANK } from './menu.types';

export const getMenu = () => async dispatch => {
    const response = await fetch(`${apiUrl}/menu`);
    if (response.ok) {
        const menuData = await response.json();
        dispatch({ type: GET_MENU, payload: menuData })
    }
}

export const increaseCategoryRank = category => dispatch => {
    dispatch({ type: INCREASE_CATEGORY_RANK, payload: category })
}

export const decreaseCategoryRank = category => dispatch => {
    dispatch({ type: DECREASE_CATEGORY_RANK, payload: category })
}

category-arrows.component.jsx:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { increaseCategoryRank, decreaseCategoryRank } from '../../redux/menu/menu.actions';
import './category-arrows.styles.scss';

class CategoryArrows extends Component {

    render() {

        const { category, increaseCategoryRank, decreaseCategoryRank } = this.props;

        return (
            <div class="arrows-container">
                <div class="up-arrow" onClick={() => this.props.increaseCategoryRank(category)}></div>
                <div class="category-rank">
                    <p>{category.rank}</p>
                </div>
                <div class="down-arrow" onClick={() => this.props.decreaseCategoryRank(category)}></div>
            </div>
        )
    }
}

export default connect(null, { increaseCategoryRank, decreaseCategoryRank } )(CategoryArrows);

For my Reducer function, the initial state is retrieved from a database. The Reducer code deals with the menu array, which is an array of objects:

enter image description here

I want to copy the menu array from the state in my Reducer function, so that I can sort it, and then reassign the sorted menu array to the state.

I have tried to console.log() the state to see what it is in my Reducer function. When I click on the up-arrow div in category-arrows.component.jsx, the INCREASE_CATEGORY_RANK action is dispatched. When I check the Console, I get the following:

enter image description here

However when I copy the menu array from the state in the INCREASE_CATEGORY_RANK case in my Reducer function, I get the following error:

enter image description here

I am not sure why I am getting the above error and how to resolve it. Any insights are appreciated.

Upvotes: 0

Views: 3721

Answers (1)

Samuel Vaillant
Samuel Vaillant

Reputation: 3847

It looks like the reducer expect an array not an object:

export default (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case INCREASE_CATEGORY_RANK: { 
            return [...state].sort((a,b) => (a.rank > b.rank) ? 1 : -1);
        }
    }
}

Upvotes: 2

Related Questions