0

I have Restaurants component which is responsible for listing restaurants from Zomato Dev APIs. I have passed Category and City from other components to Restaurants component.

I am opening Restaurants component with below code :

this.props.history.push(
        {
            pathname : '/restaurants', 
            valueCategory : this.props.location.valueA,  // CATEGORY
            valueCity : this.state.cities[index] // CITY
        });

I want to use these valueCategory and valueCity in calling /search api.

Code :

class Restaurants extends React.Component {

constructor(props) {
    super(props);
    this.componentDidMount = this.componentDidMount.bind(this);
    this.getRestaurants = this.getRestaurants.bind(this);
}

componentDidMount() {
    // I AM GETTING ERROR 'TypeError: Cannot read property 'name' of undefined' ON THIS LINE
    console.log("Component Did Mount Restaurant : " + this.props.location.valueCity.name);
}

 componentDidUpdate(prevProps, prevState, snapshot){
    console.log("Component Did Update :", prevProps); 
    //THIS PRINTS prevProps, WHICH CONTAINS valueCity and valueCategory but I am unable to access them
    return false;
}

render() {
    let category, city;
    category = '';
    city = '';

    if(!isUndefined(this.props.location.valueCategory)) {
        category = <p>You selected Category as : {this.props.location.valueCategory.categories.name}</p>;
    }

    if(!isUndefined(this.props.location.valueCity)) {
    // STRANGLY, THIS LINE WORKS FINE! WHEN I AM ACCESSING valueCity.name
        city = <p>You selected City as : {this.props.location.valueCity.name}</p>;
    }

    console.log(this.props.location);
    return (
        <div> 
            {category}
            {city}
        </div>
    );
}
}

enter image description here

My question is :

  • I am able to access {this.props.location.valueCity.name} in render() method
  • But I am not able to access the same in componentDidMount() or any other method? I am getting crash

TypeError: Cannot read property 'name' of undefined

Kushal
  • 8,100
  • 9
  • 63
  • 82
  • Is your location accessible right on rendering or it's fetched? – Maciej Trojniarz Dec 10 '19 at 08:56
  • componentDidMount will be called immediately after the first render.So may be your network is taking some time to load the data...but ,your trying to access the data which is the result of api call right?...Try to add check before accessing object property..For example: const { location = {} } = this.props; const {valueCity = {} } = location || {}; const {name = {}} = valueCity || {}. or you can use lodash get – Rajesh Kumaran Dec 10 '19 at 09:23
  • @RajeshKumaran No, I am not trying to access API result. I am trying to access `props` passed from top level component. I have not called API until now. – Kushal Dec 10 '19 at 09:24
  • @MaciejTrojniarz location is accessible in `render()` method – Kushal Dec 10 '19 at 09:25
  • the error is due to your props doesn't have the key named valueCity inside location. – Rajesh Kumaran Dec 10 '19 at 09:25
  • can u print the props inside componentDidMount and check whether you have valueCity inside location prop – Rajesh Kumaran Dec 10 '19 at 09:26
  • When I added `console.log("Component Did Mount Restaurant : " + this.props);` in `componentDidMount()`, it prints `Component Did Mount Restaurant : [object Object]` – Kushal Dec 10 '19 at 09:28

1 Answers1

0

Have you tried componentDidUpdate life cycle method? compare the props incoming to this method

        this.state={
        valueCategory:"",
        valueCity:"" //you can chose any data type, 
        checker:true  
        }

        this.stateUpdater(prevProps){
           let valueCategory={this.props};
           let valueCity={this.props};

           if(this.props.valueCategory===undefined){/*check the data  
           what is incoming and use condition accrodingly*/ 

           this.setState({valueCategory:prevProps.location.valueCategory
           ,checker:false})
           }else{
             //no update
              this.setState({checker:false})
            }
        componentDidUpdate(prevProps, prevState, snapshot){
           console.log("see the props",prevProps,this.props);
           if(this.state.checker)              
              this.stateUpdater(prevProps);
           else{
              console.log("do nothing") 
           }
           return false;
       }

**check and let me know

warmachine
  • 376
  • 1
  • 8
  • But put a condition there ,otherwise it will keep setting state,keep coding – warmachine Dec 10 '19 at 10:17
  • can you screen shot your output? – warmachine Dec 10 '19 at 10:53
  • Basically, This lifecycle method is not getting called for me currently – Kushal Dec 10 '19 at 10:55
  • can you share the updated component code please? with this method – warmachine Dec 10 '19 at 11:16
  • I have updated question and also posted screenshot. Please have a look – Kushal Dec 10 '19 at 12:04
  • I am updating my reply with an idea ,let me know if it works or not,but we have to use state,check once. – warmachine Dec 10 '19 at 12:38
  • In line `this.setState({valueCategory:prevProps.location.valueCategory.name ,checker:false})`, It is giving same error, unable to read property `'name'` – Kushal Dec 11 '19 at 07:11
  • as per the screenshot ,you are getting prevProps inside componentDidUpdate,i dont understand why you are not able to pass that to that function – warmachine Dec 11 '19 at 08:40
  • Yes, It got printed in console without any issue. But, I am unable to access it. – Kushal Dec 11 '19 at 09:06
  • you can not access prevProps outside componentDidUpdate,that's why you need to pass to that function and convert it into state,then use the state data in your component – warmachine Dec 11 '19 at 09:14
  • After passing the props, i received in `prevProp` parameter in `stateUpdater(prevProp)` function, but is not getting accessed. Your posted code won't work, if you pass any thing in `props.location` in this component – Kushal Dec 11 '19 at 09:42
  • hey i am sorry i did not write the location in the code like "prevProps.location.valueCategory",i updated the reply my bad!! – warmachine Dec 11 '19 at 10:20
  • Hey did you run your code? It will give access error at `location.valueCategory.name` – Kushal Dec 11 '19 at 10:40
  • can you please post that error,i am sorry bro ,its taking longer than expected – warmachine Dec 11 '19 at 11:22