Reputation: 118
Component doesn't retrieve data from Firebase before it mounts.
const mapStateToProps = (state, ownProps) => {
return {
products: state.firestore.ordered.products
};
};
when I test for the props after it mounts...
componentDidMount() {
console.log(this.props);
}
The value of this.props.product is undefined.
If I console.log the state parameter inside mapStateToProps() I immediately get two console.logs of undefined and after a short while, I receive the actual array that I wanted.
const mapStateToProps = (state, ownProps) => {
const products2 = state.firestore.ordered.products;
console.log(products2); //returns 2 console logs of undefined,
// after a second (after the component mounts) it gives me the data
return {
products: state.firestore.ordered.products
};
};
The reason why that is an issue is when I want to render the component using the data from the Firebase.
<div className="item-render-space">
{products
.filter(
eachProduct =>
eachProduct.landingPageCategory.indexOf(this.props.category) >
-1
)
.map(eachProduct => (
<div className="each-product" key={eachProduct.id}>
<Link to={"/product/" + eachProduct.id}>
<img src={eachProduct.image} alt="#" />
<p className="product-price">{eachProduct.price}</p>
<p className="product-name">
{nameShortener(eachProduct.name)}
</p>
</Link>
</div>
))}
</div>
I get an error screen because the variable "products" is undefined because The data from the firebase hasn't reached the component when it started rendering.
How to fix this issue?!
EDIT: Here is the rootReducer:
const rootReducer = combineReducers({
firestore: firestoreReducer, //connects to firestore
live: liveReducer, //used locally for opening bootstrap modals
products: productsReducer, //previous products store before implementing Firestore
firebase: firebaseReducer //connects to firebase
});
Upvotes: 1
Views: 283
Reputation: 38807
Try using conditional rendering to avoid attempting to execute Array.prototype.filter() and Array.prototype.map() on undefined
. The following would check for products
to be truthy and have a length
of greater than 0:
<div className="item-render-space">
{products && products.length > 0 && products
.filter(
eachProduct =>
eachProduct.landingPageCategory.indexOf(this.props.category) >
-1
)
.map(eachProduct => (
<div className="each-product" key={eachProduct.id}>
<Link to={"/product/" + eachProduct.id}>
<img src={eachProduct.image} alt="#" />
<p className="product-price">{eachProduct.price}</p>
<p className="product-name">
{nameShortener(eachProduct.name)}
</p>
</Link>
</div>
))}
</div>
Hopefully that helps!
Upvotes: 1