can't get data from mongodb in React - javascript

i have an app which loads data from mongodb to list component like this
React.render(<ProductsList url="http://localhost:3000/data"/>, document.getElementById('products'));
and then i try make a http get call to ge the data like this
var ProductsList = React.createClass({
loadData: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
success: function(data) {
<ProductsList url={data}/>
},
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}
});
},
render: function() {
this.loadData();
var products = this.props.url.map(function(product) {
return (
<li key={product._id}>
<Product data={product} />
</li>
)
});
return (
<ul className="clearfix">
{products}
</ul>
);
}
});
but when i load the app i get this error Uncaught TypeError: this.props.url.map is not a function what could the problem be ?

map is not a function for strings, check the documentation for array map: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Furthermore, not related to your error, but your function loadData returns undefined, because you are just making the ajax call. In order to make this work, you need to use the state object of the react component call this.setState() in your success/error hooks.

it's seems like you are not clear about the props and state of React you have to follow in below mentioned way
var ProductsList =React.createClass({
getInitialState:function()
{
return{
url:[]
}
},
componentDidMount:function()
{
var that=this;
$.ajax({
url: 'https://api.github.com/users/mralexgray/repos',
dataType: 'json',
success: function(data) {
that.setState({url:data});
},
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}
});
},
ChangeContent:function()
{
this.setState({content:"change Content"});
},
render:function()
{
var Products = this.state.url.map(function(product) {
return (
<li key={product._id}>
{product.full_name}
</li>
)
});
return(
<div>
{Products}
</div>
)
}
});
React.render(
<ProductsList />,
document.getElementById('example')
);
Demo

Related

Display array element ReactJS

UPD: How can I display elment of the array in my component (WeatherCityName - h2)? It can be seen that the array is loaded, but when I point out the property - an error occurs, it may be a problem in the syntax?
var WeatherBox = React.createClass({
handleWeatherSubmit: function(text) {
$.ajax({
url: this.props.url,
dataType: 'json',
type: 'POST',
data: 'cityName=' + text,
success: function(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: []};
},
render: function() {
return (
<div className="wetherBox">
<h1> Weather</h1>
<WeatherForm onWeatherSubmit={this.handleWeatherSubmit} />
<WeatherCityName data={this.state.data[0]} />
<WeatherList data={this.state.data} />
</div>
);
}
});
var WeatherCityName = React.createClass({
render: function(){
return(
<h2>{this.state.data[0].cityName}</h2>
);
}
});
Sure, just put <h2>{weatherItem.cityName}</h2> directly in the <div>.
var WeatherList = React.createClass({
render: function() {
var weatherNodes = this.props.data.map(function(weatherItem) {
return (
<div className="city-item-with-title">
<h2>{weatherItem.cityName}</h2>
<WeatherItem
cityid={weatherItem.cityid}
type={weatherItem.type}
src={weatherItem.src}
temp={weatherItem.temp}
tempFrom={weatherItem.tempFrom}
tempTo={weatherItem.tempTo}
key={weatherItem.id}
/>
</div>
);
});
return (
<div className="weatherList">
{weatherNodes}
</div>
);
}
});
Edit: I'm not sure which weather item you want to use as a title, perhaps this.props.data[0]?
Edit 2: Just assumed you want to use the first weather item.
Edit 3: One title for each weatherItem, grouped inside a div together with the corresponding weatherItem.

Can't get data from React state

I have the following ReactJS code:
var CommentList = React.createClass({
render: function(){
var commentNodes = this.props.data.map(function(comment){
return (
<Comment author={comment.author} key={comment.id}>
{comment.text}
</Comment>
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
And in CommentBox....
var CommentBox = React.createClass({
loadCommentFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(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.loadCommentFromServer();
setInterval(this.loadCommentFromServer, this.props.pollInterval);
},
render: function() {
return (
<div className = "commentBox" >
<h1> Comments </h1>
<CommentList data ={ this.state.data } />
<CommentForm />
</div>
);
}
});
In getInitialState(), I already assign value for data and in CommentList also add property data which get value from state.
When I try to run, I got this error:
Cannot read property 'map' of undefined in CommentList.
It looks like you simply aren't getting the data you want back from the jQuery.ajax.
success: function(data) {
// before setting state, log here and find out what data is
// it could need to be turned into JSON? data = data.toJSON();
// or simply this to be safe
data = data || [];
this.setState({
data: data
});
}

React Tutorial and Sinatra API: Uncaught TypeError: this.props.data.map is not a function

I know, there are hundreds of questions with the same title, but nothing helped my get a solution for my problem. so I worked through the official react js tutorial and build a small API with sinatra to test things.
so everything works really good. except of one error I see in the console when submitting a new "Joke" (called them jokes instead of comments ;)) via AJAX.
app.js:66 Uncaught TypeError: this.props.data.map is not a function
This happens when I click on submit. I logged the state when submitting the form and everything seems to be okay (array with the temporary objects).
so the new Joke is being added and written to the database. It works but i don't know why I'm getting the Uncaught TypeError in the console.
thanks in advance!
var JokeBox = React.createClass({
loadJokesFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
handleJokeSubmit: function(joke) {
var jokes = this.state.data;
var tmpJoke = jQuery.extend({}, joke)
tmpJoke.id = new Date();
tmpJoke.likes = 0;
jokes.unshift(tmpJoke);
this.setState({data: jokes}, function(){
$.ajax({
url: this.props.url,
dataType: 'json',
type: 'POST',
data: joke,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
this.setState({data: jokes});
console.error(this.props.url, status, err.toString());
}.bind(this)
});
});
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
this.loadJokesFromServer();
setInterval(this.loadJokesFromServer, this.props.pollInterval);
},
render: function() {
return (
<div className="jokes">
<h1>Jokes</h1>
<JokeForm onJokeSubmit={this.handleJokeSubmit} />
<JokeList data={this.state.data} />
</div>
);
}
});
var JokeList = React.createClass({
render: function() {
var jokeNodes = this.props.data.map(function(joke) {
return (
<Joke content={joke.content} key={joke.id} likes={joke.likes} />
);
});
return (
<div className="jokeList">
{jokeNodes}
</div>
);
}
});
var JokeForm = React.createClass({
getInitialState: function() {
return {content: ''};
},
handleContentChange: function(e) {
this.setState({content: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var content = this.state.content.trim();
if (!content) {
return;
}
this.props.onJokeSubmit({content: content});
this.setState({content: ''});
},
render: function() {
return (
<form className="jokesForm" onSubmit={this.handleSubmit}>
<input
type="text"
placeholder="Your Joke!"
value={this.state.content}
onChange={this.handleContentChange}
/>
<input type="submit" value="Send joke" />
</form>
);
}
});
var Joke = React.createClass({
render: function() {
return (
<div className="joke">
<p className="jokeContent">{this.props.content}</p>
<p className="jokeLikes">{this.props.likes}</p>
</div>
);
}
});
ReactDOM.render(
<JokeBox url="/api/jokes" pollInterval={2000} />,
document.getElementById('app')
);
// EDIT
So I played around with the sample tutorial repo from the tutorial. I log the data in the handleSubmit in the success function right before the state is set. And I figured out: my data is ja object of the actual new Joke, in the sample tutorial it is an array of all comments. How could this be? I can't find my mistake...
try
handleJokeSubmit: function(joke) {
let {data}= this.state;
$.post(this.props.url, joke, res=>{
this.setState({data:[res,...data]});
})
.fail( err=>alert('Error: ' + err.responseText));
}
///EDIT es5
handleJokeSubmit: function(joke) {
var data = this.state.data;
$.post(this.props.url, joke, function(res){
this.setState({data:[res].concat(data)});
}.bind(this))
.fail( function(err){alert('Error: ' + err.responseText)});
}

ReactJS Props and bubbling

I'm having a hard time understanding why I can't do something like this.
loadPostsFromServer: function() {
$.ajax({
url: '/allPosts',
dataType: 'json',
success: function(data) {
console.log(data);
this.setState({posts:data, items:data});
//this.setState({items:data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url,status, err.toString());
}.bind(this)
});
},
loadUserFromServer: function() {
$.ajax({
url: '/user',
dataType: 'json',
success: function(data) {
this.setState({user:data.local});
//console.log(this.state.user);
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url,status, err.toString());
}.bind(this)
});
},
getInitialState: function() {
return {
posts: [],
items: [],
user: []
}
},
componentDidMount: function() {
this.loadPostsFromServer();
this.loadUserFromServer();
//this.setState({items: this.state.posts});
//setInterval(this.loadPostsFromServer, this.props.pollInterval);
},
render: function() {
<div className="Posts">
<List user={this.state.user} posts={this.state.items} />
</div>
}
Where List can be something like this and can't do the this.props.user print
var List = React.createClass({ //has to be called list
render: function() {
return (
<p>{this.props.user}</p>
<ul>
{
this.props.posts.map(post){
return (<p>{post.title}</p>)
})
}
</ul>
)
}
});
but can do this:
var List = React.createClass({
render: function() {
return (<p>{this.props.user}</p>)
}
});
Basically I'm passing two props in my real function, and the ajax call is delivering down a array user, with user info, and array post with post info. I can display the post info fine, and the user info is complete as well, however I cannot actually display the user info received from the ajax get call. I printed out the state of the array as well and it was complete and filled. However passed down it would return messages like cannot read {this.props.user.firstName} and such, however writing it the second way and not including posts, it works fine. How can I use both props in a map function?
Be careful, in render function, you always need a wrap tag to make React work. You should add <div> tag to the render of List component.
var List = React.createClass({ //has to be called list
render: function() {
return (
<div> <-- ALWAYS HAS A WRAP TAG
<p>{this.props.user}</p>
<ul>
{
this.props.posts.map(post){
return (<p>{post.title}</p>)
})
}
</ul>
</div>
)
}
});
This code below works because there is <p> to wrap contents.
var List = React.createClass({
render: function() {
return (<p> <-- WRAP TAG
{this.props.user}
</p>)
}
});

Uncaught TypeError: Cannot read property 'map' of undefined with React

I have implemented a little test application in React to fetch data via AJAX, but it is not working as inteded, hence i get following error:
Uncaught TypeError: Cannot read property 'map' of undefinedInline JSX script
Code is as following:
<div id="content"></div>
<script type="text/jsx">
var Bodypart = React.createClass({
render: function() {
return (
<div>
{this.props.name}
</div>
)
}
})
var BodypartList = React.createClass({
getInitialState: function() {
return {data: []};
},
componentWillMount: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
success: function(data) {
this.setState({bodyparts: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
render: function() {
var bodypartItems = this.state.bodyparts.map(function (bodypart) {
return (
<Bodypart
name={bodypart.name}
/>
);
});
return (
<div>
{bodypartItems}
</div>
);
}
});
React.render(
<BodypartList url="/api/bodyparts/" />,
document.getElementById('content')
);
</script>
The response from /api/bodyparts/:
{
"bodyparts": [
{
"id": 1,
"name": "Face"
},
{
"id": 3,
"name": "Mouth"
},
{
"id": 2,
"name": "Nose"
}
]
}
At initial render this.state.bodypartsis undefined hence the error you got.
you should return
{bodyparts:[]}
from getInitialState.
Also in your success callback you should set state like:
this.setState(data);
because your api already returns bodyparts as part of its result.
this.state.bodyparts is undefined. the component is rendering before the ajax has completed. Try setting an initial state

Categories

Resources