I have a presentational component, , which takes a {props} object and populates itself with the proper values.
I also have a container component, , which is supposed to map state to props, take the array of objects representing the plots, map it and initialize a from each one.
This is throwing me an error-Uncaught (in promise) TypeError: Cannot read property 'name' of undefined. The "name" in question is a property of the plot.
Looking at the documentation, this error typically happens when we import a component with curly braces when we should import it without, but that's not the case here.
I have a feeling that what is going on is that I am improperly passing the props to the element, but am not sure of the right way to do it.
Plot.js:
import React from 'react';
const Plot = ({ props }) => {
return (
<div className="media col-md-4">
<div className="media-left">
<a href="#">
<img className="media-object" src="http://placehold.it/200/550" alt="Placehold" />
</a>
</div>
<div className="media-body">
<h4 className="media-heading">{props.name}</h4>
<ul>
<li><strong>Grower: </strong> {props.grower}</li>
<li><strong>Region: </strong> {props.region}</li>
<li><strong>Current State: </strong> {props.currentState}</li>
<li><strong>Next State: </strong> {props.nextState}</li>
<li><strong>Days To Next State: </strong> {props.daysToNext}</li>
<br />
<span class="pull-right">
<i id="like1" class="glyphicon glyphicon-thumbs-up"></i> <div id="like1-bs3"></div>
<i id="dislike1" class="glyphicon glyphicon-thumbs-down"></i> <div id="dislike1-bs3"></div>
</span>
</ul>
</div>
</div>
);
};
export default Plot;
Dashboard.js:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../actions';
import Plot from './plot';
class Dashboard extends Component {
componentWillMount() {
this.props.fetchMessage();
this.props.fetchPlots();
}
render() {
const plots = this.props.plots;
return (
<div>
<span>{this.props.message}</span>
<div className='container'>
<div className="row">
{plots && plots.map((plot) => <Plot key={plot._id} name={plot.name} grower={plot.grower} region={plot.region} currentState={plot.currentState} nextState={plot.nextState} daysToNext={plot.daysToNext}/>)}
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
message: state.auth.message,
plots: state.auth.plots
}
}
export default connect(mapStateToProps, actions)(Dashboard);
EDIT:
This is fetchPlots(). I know that it's working and that plots are available as props, because when I add a console.(log) statement before the return statement in dashboard.js, I can see them, and they're fine, with all necessary properties.
export function fetchPlots() {
return function (dispatch) {
axios.get(`${ROOT_URL}/plots`, {
headers: {
authorization: localStorage.getItem('token')
}
})
.then(response => {
dispatch({
type: FETCH_PLOTS,
payload: response.data
});
});
}
}
My reducer:
import {AUTH_USER, UNAUTH_USER, AUTH_ERROR, FETCH_MESSAGE, FETCH_PLOTS} from '../actions/types';
export default function(state={}, action){
switch(action.type){
case AUTH_USER:
return{...state, error:'',authenticated:true};
case UNAUTH_USER:
return{...state, authenticated:false};
case AUTH_ERROR:
return { ...state, error: action.payload };
case FETCH_MESSAGE:
return { ...state, message: action.payload }
case FETCH_PLOTS:
return { ...state, plots: action.payload }
}
return state;
componentDidMount(). Please check and let us know if it helps. Btw can you paste yourfetchMessage()andfetchPlots()snippets