I'm new to ReactJS and am attempting to render an individual object that contains an array of objects.
But I can't get around the Uncaught TypeError: this.props.data.map is not a function
error.
How do I get at the assets array within the parent object (ie data)?
Here's my JS currently:
<script type="text/babel">
var ProjectContainer = React.createClass({
loadProjectsFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
console.log(data)
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
getInitialState: function () {
return {data: []};
},
componentDidMount: function() {
this.loadProjectsFromServer();
setInterval(this.loadProjectsFromServer, this.props.pollInterval);
},
render: function () {
return (
<Project data={ this.state.data } />
);
}
});
var Project = React.createClass({
rawMarkup: function() {
var rawMarkup = this.props.data.description_html;
return { __html: rawMarkup };
},
render: function() {
var assetNodes = this.props.data.map(function (asset) {
return (
<Asset key={ asset.pk } art={ asset.art } project={ asset.project } description={ asset.description } />
);
});
return (
<div>
{ this.props.data.assets }
<header>
<h2 className="lead_head">{ this.props.data.client_name }</h2>
</header>
<span dangerouslySetInnerHTML={ this.rawMarkup() } />
<ul className="project_asset_list">
{ assetNodes }
</ul>
</div>
);
}
});
var Asset = React.createClass({
render: function() {
return (
<li className="asset">
<span className="asset_description">{ this.props.project }{ this.props.description }</span>
<a href={ this.props.art } data-title={ this.props.project } data-lightbox="roadtrip">
<img src={ this.props.art } alt={ this.props.description } />
</a>
</li>
)
}
});
ReactDOM.render(
<ProjectContainer url="{% url 'portfolio_project_detail_api' slug=slug %}" pollInterval={2000} />,
document.getElementById('project_indiv')
);
</script>
Here's the JSON I'm working with:
{
"pk": 2,
"client_name": "Paz Studios",
"slug": "paz-studios",
"description": "[Paz Studios](https://www.facebook.com/pazstudios) offers yoga and Pilates for students at all levels. (I'm a devoted beginner, and their instructors do a great job of making me feel like I belong, alongside all the other limber wonders.)\r\n\r\nI worked with them as they prepared for their grand opening in November 2013 to craft a logo that found an intersection of simplicity and nature.\r\n\r\nI've continued working with them to create posters, flyers, and other promotional materials. And they've continued to work with me: I've got their advanced classes on my bucket list.",
"description_html": "<p><a href=\"https://www.facebook.com/pazstudios\">Paz Studios</a> offers yoga and Pilates for students at all levels. (I’m a devoted beginner, and their instructors do a great job of making me feel like I belong, alongside all the other limber wonders.)</p>\n<p>I worked with them as they prepared for their grand opening in November 2013 to craft a logo that found an intersection of simplicity and nature.</p>\n<p>I’ve continued working with them to create posters, flyers, and other promotional materials. And they’ve continued to work with me: I’ve got their advanced classes on my bucket list.</p>",
"lead_art": "http://127.0.0.1:8000/media/images/portfolio/projects/portfolio-preview-paz.png",
"completion_date": "2013-11-01",
"project_detail": {
"self": "http://127.0.0.1:8000/work/paz-studios/?format=json"
},
"assets": [
{
"pk": 3,
"description": "logo",
"project": "Paz Studios",
"art": "http://127.0.0.1:8000/media/images/portfolio/assets/portfolio-asset-paz-logo.png"
},
{
"pk": 4,
"description": "schedule poster (11x17)",
"project": "Paz Studios",
"art": "http://127.0.0.1:8000/media/images/portfolio/assets/paz-march-flyer_2.png"
},
{
"pk": 5,
"description": "class flyer (8.5x11)",
"project": "Paz Studios",
"art": "http://127.0.0.1:8000/media/images/portfolio/assets/paz-vinyasa-class_2.png"
}
]
}
First in your Ajax all you have write the line in success function this.setState({data: data});
it's not going to work, your loadProjectsFromServer function should be look like
loadProjectsFromServer: function() {
var Current=this;
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
console.log(data)
Current.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
when you will write keyword this
and the scope of this keyword is your ajax call and that function don't have a state so you have to store your component in variable and then use that variable to access the state in your ajax call
Second if you find the data in your component then your data should in form of JSON if your data in form of object then you have to write like
var actualdata=JSON.parse(this.props.data);
var assetNodes = Object.keys(actualdata).map(function (asset) {
return (
<Asset key={ actualdata[asset].pk } art={ actualdata[asset].art } project={ actualdata[asset].project } description={ actualdata[asset].description } />
);
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.