user7319004
user7319004

Reputation:

Looping JS object only works with return statement otherwise it throw undefined

This first method with return statement inside JSX works correctly

  <div>
    {this.state.list.map(item => {
      return <h6>{item.location.formattedAddress[0]}</h6>
    })}
  </div>

But this normally should give the same result :

 render() {
    const listItems = this.state.list.map((item, index) => (
        <h6>{item.location.formattedAddress[0]}</h6>
    ));
    return (
      {listItems}
    )
 }

TypeError: Cannot read property 'map' of undefined

Also it runs on mounting the page rather than when executing the function to load the dat from API, please someone assist

Upvotes: 0

Views: 48

Answers (2)

Tu Nguyen
Tu Nguyen

Reputation: 10179

Try this


This is the first method like you did:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        { id: 1, title: 'React' },
        { id: 2, title: 'Angular' },
        { id: 3, title: 'Vue' }
      ]
    };
  }
  render() {
    return (
      <div>
        {this.state.list && this.state.list.map(li => (
          <h2 key={li.id}>{li.title}</h2>
        ))}
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root">
  <div>


And this is the second method that you expected it to work

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        { id: 1, title: 'React' },
        { id: 2, title: 'Angular' },
        { id: 3, title: 'Vue' }
      ]
    };
  }
  render() {
    const listItems = this.state.list ? this.state.list.map(li => (
      <h2 key={li.id}>{li.title}</h2>
    )) : '';
    return <div>{listItems}</div>;
  }
}
ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"><div>


I added some small checks before rendering to ensure that you won't get the error: Cannot read property 'map' of undefined

Upvotes: 1

Filipe Valente
Filipe Valente

Reputation: 406

I would suggest you to turn listItems in to a method like renderListItems() and add a return before mapping the array.

renderListItems = () => {
    return this.state.list.map((item, index) => (
        <h6>{item.location.formattedAddress[0]}</h6>
    ));
}

Then call it in your render method like

render() {
    return (
        <div>
            {this.renderListItems()}
        </div>
    )
}

Hope this helps :)

Upvotes: 0

Related Questions