Jay Jeong
Jay Jeong

Reputation: 994

React syntax does not work

componentDidMount() {
    const restaurants = Restaurant.all()
    restaurants.then( rests => {
        this.setState({
            restaurants: rests
        })
    })
}


render() {
        const { restaurants } = this.state;

        return (
            <main className="SearchRestaurantsPage" style={{textAlign: 'center'}}>
                <Chosen className="Chosen-select" onChange={ value => console.log(value) }>
                    {    
                        restaurants.map( restaurant => {

                            return restaurant ?
                                ( <option key={restaurant.id}>{ restaurant.name }</option> )
                                :
                                ''
                        })
                    }
                </Chosen>
            </main>
        );
    }

I have my react code above and trying to return a mapped array that is supposed to be something like

[<option key={1}>first</option>, <option key={2}>two</option>, <option key={3}>three</option>]

It works if I put a randomly created array like this,

render() {
        const { restaurants } = this.state;

        return (
            <main className="SearchRestaurantsPage" style={{textAlign: 'center'}}>
                <Chosen className="Chosen-select" onChange={ value => console.log(value) }>
                    {    
                         [<option key={1}>first</option>, <option key={2}>two</option>, <option key={3}>three</option>]
                    }
                </Chosen>
            </main>
        );
    }

but no matter what I do with the map method, it just doesn't show anything. I have already checked there is an array containing elements assigned to this.state.restaurant.

Upvotes: 0

Views: 74

Answers (2)

Kavindu Wijesuriya
Kavindu Wijesuriya

Reputation: 157

The issue might be where you declared the restaurent constant from the state. I've written a sample code that works below.

import React from 'react';

const restaurentData = [
  {
    id: 1,
    name: 'name 1'
  },
  {
    id: 2,
    name: 'name 2'
  },
  {
    id: 3,
    name: 'name 3'
  }
]
class Hello extends React.Component {
  constructor() {
    super();

    this.state = {
      restaurents: restaurentData
    }
  }

  render () {
    const restaurents = this.state.restaurents;
    return (
      <ul>
        {restaurents.map(restaurent => {
          return restaurent 
            ? (<li key={restaurent.id}>{`${restaurent.id} -- ${restaurent.name}`} </li>) 
            : null;
        })}
      </ul>
    )
  }
}

export default Hello;

Upvotes: 0

Nik
Nik

Reputation: 2272

componentDidMount is called after the first render. Consequently your restaurants is undefined when the first render processed.

You can check if restaurants exists in render method:

componentDidMount() {
    const restaurants = Restaurant.all()
    restaurants.then( rests => {
        this.setState({
            restaurants: rests
        })
    })
}


render() {
        const { restaurants } = this.state;

        return (
            <main className="SearchRestaurantsPage" style={{textAlign: 'center'}}>
                <Chosen className="Chosen-select" onChange={ value => console.log(value) }>
                    {    
                        restaurants && restaurants.map( restaurant => {

                            return restaurant ?
                                ( <option key={restaurant.id}>{ restaurant.name }</option> )
                                :
                                null
                        })
                    }
                </Chosen>
            </main>
        );
    }

Also, check if your state is defined in the constructor or as the class property.

So the whole component could be the follow:

class Rests extends React.Component {    
    state = {restaurants: null};

    componentDidMount() {
        const restaurants = Restaurant.all()
        restaurants.then( rests => {
            this.setState({
                restaurants: rests
            })
        })
    }


    render() {
        const { restaurants } = this.state;

        if (!restaurants) {
           return null; // or you can return <LoadingSpinner /> here
        }

        return (
            <main className="SearchRestaurantsPage" style={{textAlign: 'center'}}>
                <Chosen className="Chosen-select" onChange={ value => console.log(value) }>
                    {    
                        restaurants.map( restaurant => {

                            return restaurant ?
                                ( <option key={restaurant.id}>{ restaurant.name }</option> )
                                :
                                null
                        })
                    }
                </Chosen>
            </main>
        );
    }
}

In the last example, we render nothing if there is no any data in restaurants. After we fetch data we rerender component and show options to users

Upvotes: 4

Related Questions