0

Once again, I'm facing a very common mistake "Cannot read property 'map' of undefined". I have a initial list of items (movies) loading properly inside a <ul><li></li></ul>. However after dispatching my action by clicking my button, the error happen. I can actually see the state updated in my redux dev tool (even with the error) but I also can see that the change doesn't impact my store state in my react dev tool.

So here is my reducer :

export default function moviesReducer(state = {items}, action) {
  if(action.type === 'SET_MOVIES_FILTER') {
    return update(state.items, {$splice: [[1,3]]})
  }
    return state;
  }

Here is my item list (from here post) :

let items = [{
  title: 'Mad max',
  year: 2015,
  rating: 8,
  genre: 'fantasy',
}, {
  title: 'Spider man 2',
  year: 2014,
  rating: 7,
  genre: 'fantasy',
}, {
  title: 'Iron man 3',
  year: 2013,
  rating: 7,
  genre: 'fantasy',
}, {
  title: 'Dumb and Dumber To',
  year: 2014,
  rating: 5,
  genre: 'comedy',
}, {
  title: 'Ted 2',
  year: 2015,
  rating: 6,
  genre: 'comedy',
}];

Here is my action :

export const SetMoviesFilter = () => {
  return {
    type: 'SET_MOVIES_FILTER'
  };
};

And here is my components :

const movieTable = ({testmovie, movieTable }) => {

        return (

        <div>
            <button onClick={movieTable}>testbutton</button> 
            <ul>
            {testmovie.map((m, i) =>
        <li key={i}>{m.year} - {m.title}.({m.genre}) - {m.rating}</li>
      )}
            </ul>
        </div> )
    }

function mapStateToProps(state) {
  return {
      testmovie: state.moviesReducer.items

  };
};


const mapDispachToProps = (dispatch) => {
    return {
  movieTable: () => {dispatch (SetMoviesFilter());
        },
    };
};


const AppMovie = connect(mapStateToProps, mapDispachToProps)(movieTable);

Where am I wrong ? what should I do ? I don't know if it's related but I can't make my jsbin work.

thanks.

4
  • testmovie is undefined. You can put a debugger in your code and open the chrome dev tools to inspect it. add debugger; on the first like of your movieTable function and it will pause on that line when you have the dev tools open in chrome. Commented Jul 27, 2016 at 19:41
  • hum... I don't understand. I didn't have any error of testmovie undefined. I actually can see the list of movies displaying with the map function <ul> {testmovie.map((m, i) => <li key={i}>{m.year} - {m.title}.({m.genre}) - {m.rating}</li> )} </ul> I only have the 'map' of undefined error when clicking on the button. Commented Jul 27, 2016 at 19:47
  • That's the only place in your code where you are using map. The error may be coming from redux or react? You can look at the stack trace in the console to get an idea about where the error might be and what's causing it. You can expand the error by clicking it in the console and view the stack trace. Commented Jul 27, 2016 at 20:02
  • and how can I define testmovie ? since It have already been defined in my mapStateToProps function no ? Or did I miss something ? Commented Jul 27, 2016 at 20:04

1 Answer 1

3

Your initial state for state.moviesReducer.items is undefined.

In your reducer export default function moviesReducer(state = {items}, action), check where is this items coming from. It is most likely undefined when the store intializes. You can give it an initial value of []

You can also avoid this problem by wrapping your <ul> in a if statement like

if (testmovie) {
  // do your testmovie render here.
}

Edit:

it looks like your reducers are mapped correctly. so state.moviesReducer is always defined.

if your initial list of items doesn't even load correctly, means your items object are causing the error.

if your initial list loads correctly, and the error occurs only after you dispatch the SET_MOVIE_FILTER action, means your update(state.items, {$splice: [[1,3]]}) is mutating your state shape.

I don't know where you are getting this update function. but i am guessing you should do return { items: update(state.items, {$splice: [[1,3]]})}

This is how I would go about debugging your code.

Sign up to request clarification or add additional context in comments.

7 Comments

Hello. Thanks. I'm going to update my post because my question doesn't seems clear but I'm kind of lost on this one. Here is what I put into Item : let items = [{ title: 'Mad max', year: 2015, rating: 8, genre: 'fantasy', }, { title: 'Spider man 2', year: 2014, rating: 7, genre: 'fantasy', },ect..., }];
in your root combineReducers, do you have moviesReducer maped to moviesReducer exactly?
yep. like this ? const todoApp = combineReducers({ todos, visibilityFilter, tableFilter, moviesReducer, });
the thing is I can actually see my action click effect on the redux dev tool. however I have this 'map' of undefined error and nothing show up.
does the initial list of items load correctly? if the error happens after you dispatch the action SET_MOVIES_FILTER. it means the update(state.items, {$splice: [[1,3]]}) is messing with your state shape.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.