Verthon
Verthon

Reputation: 3247

Undefined props from Firebase

I have data stored in Firebase, which I want to pass to child Element. The problem is, the data is undefined in render function after second or two second console.log shows desired data. When I'm trying to pass this.state.appetizers via props to MenuItem component error says that props.menu is undefined.


 constructor(){
   super();
   this.state = {
     appetizers: {},
     desserts: {},
     salads: {},
     maindishes: {}
   }
 }

 componentDidMount(){
   db.collection('menu').get().then((snapshot) => {
     snapshot.docs.forEach(doc => {
       this.setState({
         appetizers: doc.data().Appetizers,
       });
     });
   }) ;
 }

 render(){
   const {item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11, item12} = menu;
   console.log(this.state.appetizers.app1); //first log undefined, second is good
   return (
     <Fragment>
       <Navbar/>
       <section id="menu" className="section section__menu">
         <h1 className="heading mb-4">Menu</h1>
         <div className="row">
           <div className="col-lg-6 col-md-12">
             <article className="menu-section__container">
               <h2 className="menu-section__title">{item1.category}</h2>
               <ul className="menu-section__list">
                 <MenuItem menu={this.state.appetizers.app1}/>
                 <MenuItem menu={item2} />
                 <MenuItem menu={item3} />
               </ul>
             </article>
           </div>
           <div className="col-lg-6 col-md-12">
             <h2 className="menu-section__title">{item4.category}</h2>
             <ul className="menu-section__list">
               <MenuItem menu={item4}/>
               <MenuItem menu={item5} />
               <MenuItem menu={item6} />
             </ul>
           </div>

         </div>


const MenuItem = (props) => {
 //Destructing the object menu
 //console.log(props.menu);
 const {name, price, desc} = props.menu;

 return (
         <Fragment>
           <li className="menu-section__item">
             <h3>{name}</h3> <span>{formatPrice(price)}</span>
             <p className="menu-section-description">{desc}</p>
           </li>
         </Fragment>
 );
}

MenuItem.propTypes = {
 menu: PropTypes.shape({
   name: PropTypes.string.isRequired,
   desc: PropTypes.string.isRequired,
   price: PropTypes.number.isRequired
 })
};


Upvotes: 0

Views: 475

Answers (1)

aravind_reddy
aravind_reddy

Reputation: 5486

The Error is because as soon as your component gets mounted render function is executed before your database call is executed and you get the error. so instead use a condition to check if the data is undefined before passing it to the child component. When you get the data your whole component gets rerendered and your data will be passed.

<ul className="menu-section__list">
      {(this.state.appetizers.app1)?<MenuItem menu={this.state.appetizers.app1}/>:null}
       <MenuItem menu={item2} />
       <MenuItem menu={item3} />
 </ul>

Upvotes: 1

Related Questions