Shaswati Bhattacharyya
Shaswati Bhattacharyya

Reputation: 261

Map function not able to implement in reactJS app

I'm new to react and have created a simple app from a tutorial. In the tutorial, they have used stateless components whereas I changed to stateful components. But I'm getting this error

TypeError: Cannot read property 'map' of undefined

I don't know where my code is getting wrong. It seems to be all right for me.


message-list.js

import React, { Component } from 'react';
import MessageView from './message-view';

class MessageList extends Component {
  state = {
    messages: [
      {
        from: 'John',
        message: 'The event will start next week',
        status: 'unread'
      },
      {
        from: 'Martha',
        message: 'I will be traveling soon',
        status: 'read'
      },
      {
        from: 'Jacob',
        message: 'Talk later. Have a great day!',
        status: 'read'
      }
    ]
  };

  render() {
    const { messageViews } = this.state.messages;
    console.log(messageViews);
    return (
      <div>
        <h1>List of Messages</h1>
        {messageViews.map(msgList => (
          <MessageView message={msgList.messages} />
        ))}
      </div>
    );
  }
}
export default MessageList;

message-view.js

import React, { Component } from 'react';

class MessageView extends Component {
  render() {
    const list = this.props.message;
    console.log(list);

    return (
      <div className="container">
        <div className="from">
          <span className="label">From : </span>
          <span className="value">{list.name} </span>
        </div>

        <div className="status">
          <span className="label">Status : </span>
          <span className="value">{list.status}</span>
        </div>

        <div className="message">
          <span className="label">Message : </span>
          <span className="value">{list.content} </span>
        </div>
      </div>
    );
  }
}

export default MessageView;

I have tried searching why map function is not working but of no-avail. I'm very much new to react. Can someone please guide me on this.

Upvotes: 1

Views: 52

Answers (2)

Tu Nguyen
Tu Nguyen

Reputation: 10179

TypeError: Cannot read property 'map' of undefined

In order to fix this error, you should remove the curly brackets surround the messageViews like this

 render() {
    const messageViews = this.state.messages;  //removed the curly brackets
    return (
      <div>
        <h1>List of Messages</h1>
        {messageViews.map(msgList => (
          <MessageView message={msgList.messages} />
        ))}
      </div>
    );
  }

Because when you write like this:

const { messageViews } = this.state.messages

It will try to destructure the this.state.messages object and as we all see, their is no property messageViews exists. Hence, the messageViews is undefined.

And then, when you use the map() method like messageViews.map(msgList => (...)) , the program will try to call the map() method of an undefined variable. That is why you got the error: Cannot read property 'map' of undefined

Upvotes: 1

Shubham Khatri
Shubham Khatri

Reputation: 281686

There are a few basic issues in your code

First: The state messages doesn't contain a key called as messageViews and hence you get the error

Second: In the message view Component, you aren't accessing the correct keys ie. from, message instead of name, content

Working code

class MessageList extends Component {
  state = {
    messages: [
      {
        from: "John",
        message: "The event will start next week",
        status: "unread"
      },
      {
        from: "Martha",
        message: "I will be traveling soon",
        status: "read"
      },
      {
        from: "Jacob",
        message: "Talk later. Have a great day!",
        status: "read"
      }
    ]
  };

  render() {
    const { messages: messageViews } = this.state;
    console.log(messageViews);
    return (
      <div>
        <h1>List of Messages</h1>
        {messageViews.map(msgList => <MessageView message={msgList} />)}
      </div>
    );
  }
}
export default MessageList;

class MessageView extends Component {
  render() {
    const list = this.props.message;
    console.log({ list });

    return (
      <div className="container">
        <div className="from">
          <span className="label">From : </span>
          <span className="value">{list.from} </span>
        </div>

        <div className="status">
          <span className="label">Status : </span>
          <span className="value">{list.status}</span>
        </div>

        <div className="message">
          <span className="label">Message : </span>
          <span className="value">{list.message} </span>
        </div>
      </div>
    );
  }
}

CodeSandbox Demo

Upvotes: 1

Related Questions