0

I am trying to map and object in React and keep getting the following error "TypeError: Cannot read property 'map' of undefined"

My Expected Outcome

task-1 task-2 task-3 task-4

Code

import React, { Component } from 'react';


class MapEx extends Component {
  constructor(props) {
    super(props);
    this.state =  {
      tasks: {
        'task-1': { id: 'task-1', content: 'clean house' },
        'task-2': { id: 'task-2', content: 'walk dog' },
        'task-3': { id: 'task-3', content: 'Do pushups' },
        'task-4': { id: 'task-4', content: 'have a drink' }
      }
  };
}
  render() {

    const tasks = this.state.tasks
    console.log(tasks)
    return (
      <div>
        <h1>Hello</h1>
       <p> {this.tasks.map((task) => 
              task.id)}</p>


      </div>
    );
  }
}
export default MapEx;
Paul A
  • 387
  • 3
  • 13
  • 3
    `this.tasks` is undefined, you declared `const task` in the scope of render so just use `tasks.map` and as others have pointed out map is for arrays not objects so that also needs to be looked at – Quince Apr 16 '20 at 15:21
  • 2
    Map is an array method. You must first use `Object.values` to get what you want – Marlom Apr 16 '20 at 15:22

6 Answers6

2

Two issues:

  1. You reference this.tasks instead of this.state.tasks.
  2. You are using map on an object instead of an array.

Try something like this:

return (
  <div>
    <h1>Hello</h1>
    {Object.values(this.state.tasks).map(task => <p>{task.id}</p>)}
  </div>
);
arunmmanoharan
  • 2,535
  • 2
  • 29
  • 60
srk
  • 1,625
  • 1
  • 10
  • 26
0

map can only be used on arrays. To begin with, convert your data to array DS and proceed as below.

import React, { Component } from 'react';

class MapEx extends Component {
  constructor(props) {
    super(props);
    this.state =  {
      tasks: {
        'task-1': { id: 'task-1', content: 'clean house' },
        'task-2': { id: 'task-2', content: 'walk dog' },
        'task-3': { id: 'task-3', content: 'Do pushups' },
        'task-4': { id: 'task-4', content: 'have a drink' }
      }
    };
  }
  render() {

    const tasks = this.state.tasks
    console.log(tasks)
    return (
      <div>
        <h1>Hello</h1>
        {Object.values(tasks).map(task => (<p>{task.id}</p>))}
      </div>
    );
  }
}

export default MapEx;
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
arunmmanoharan
  • 2,535
  • 2
  • 29
  • 60
0

You can do something like this:

  • Destructuring state
  • As tasks is an object you can't map over it, you need to use object.keys

import React, { Component } from 'react';


class MapEx extends Component {
  constructor(props) {
    super(props);
    this.state =  {
      tasks: {
        'task-1': { id: 'task-1', content: 'clean house' },
        'task-2': { id: 'task-2', content: 'walk dog' },
        'task-3': { id: 'task-3', content: 'Do pushups' },
        'task-4': { id: 'task-4', content: 'have a drink' }
      }
    };
  }
  render() {

    const {tasks} = this.state
    console.log(tasks)
    return (
      <div>
        <h1>My tasks</h1>
        {!!tasks ? Object.values(tasks).map(task => (<p>{task.id}</p>)) : null}
      </div>
    );
  }
}
export default MapEx;

Working example on https://codesandbox.io/s/react-boilerplate-r68kh

-1

I suggest you to read the docs of map. It works with arrays and not objects. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

SylvainF
  • 229
  • 2
  • 14
-1

tasks is an object, you need to convert it into an array to make this work.

this.state =  {
      tasks: [
        { id: 'task-1', content: 'clean house' },
        { id: 'task-2', content: 'walk dog' },
        { id: 'task-3', content: 'Do pushups' },
        { id: 'task-4', content: 'have a drink' }
      ]
  };
-2

You can map over an array and here tasks is an object

Sarthak Aggarwal
  • 2,284
  • 1
  • 8
  • 12