Reputation: 33
I am very new to React, currently doing a small project of using GitHub API to return a search result via AJAX and be able to list that result on the screen. Currently I am using a for loop to iterate over the response data and saving that data to a variable, there is most likely a way better way to do this but like I said I am new. I then set the state to the returned data. The issue is in the setState it is only returning the last result saved to the variable and not the entire variable. Listed below is the entire component, any tips or advice would be greatly appreciated. Thank you!
import axios from 'axios';
import * as React from 'react';
class User extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = {
name: name,
id: '',
userInput: '',
obj: null
};
}
handleSubmit(e: any) {
axios.get('https://api.github.com/users/' + this.state.userInput + '/repos')
.then((response) => {
if (response.data.length > 0) {
console.log('success');
let data1 = JSON.stringify(response.data);
let result = JSON.parse(data1);
for (let key in result) {
let obj = result[key];
let test = obj.name;
console.log(test);
this.setState({
name: name,
id: result[0].id,
obj: test,
userInput: this.state.userInput
})
};
} else {
console.log('else is working');
}
})
.catch((error) => {
console.log('error ');
});
}
render() {
return (
<div>
<form>
<input type="text" onChange={this.handleUserInput.bind(this)} value={this.state.userInput} />
<h1>{this.state.userInput}</h1>
<button type="button" onClick={this.handleSubmit.bind(this)}>Submit</button>
</form>
<h1>Name : {this.state.name}</h1>
<h1> ID : {this.state.id}</h1>
<h1>OBJ : {this.state.obj}</h1>
</div>
);
}
}
export default User;
The result from consoling the variable test gives this console output console output
However when it is being set in obj by this.state.obj it is only showing the last item as shown here written to page
Upvotes: 2
Views: 2139
Reputation: 33
Thank you for your answers and tips I really appreciate it. What ended up happening is since I was calling setState within the for loop it was actually displaying all of the items but it was in a split second and would stop at the last so it seemed as if it was just showing the last. This is how I ended up fixing it.
handleSubmit(e: any) {
axios.get('https://api.github.com/users/' + this.state.userInput + '/repos')
.then((response) => {
if (response.data.length > 0) {
console.log('success');
let data1 = JSON.stringify(response.data);
let result = JSON.parse(data1);
let list = '';
for(let i of result) {
list += i.name + ' ';
}
console.log(list);
this.setState({
name: result[0].name,
id: result[0].id,
obj: list,
userInput: this.state.userInput
})
} else {
console.log('else is working');
}
})
.catch((error) => {
console.log('error ');
});
}
Definitely is not the best way to do this, but atleast it is working and I can work towards improving it. Thanks a lot for all the help!
Upvotes: 1
Reputation: 11
Adding to @Tyler Sebastian answer,you can do this
let items = [];
for (let key in result) {
let obj = result[key];
let test = obj.name;
console.log(test);
items.push({
name: name,
id: result[0].id,
obj: test,
userInput: this.state.userInput
});
}
this.setState({ items: items });
and, the render section ,i think you can do this:
return (
<div>
<form>
<input type="text" onChange={this.handleUserInput.bind(this)} value={this.state.userInput} />
<h1>{this.state.userInput}</h1>
<button type="button" onClick={this.handleSubmit.bind(this)}>Submit</button>
</form>
{this.state.items.map((item) => {
<h1>Name : {item.name}</h1>
<h1> ID : {item.id}</h1>
<h1>OBJ : {item.obj}</h1>
})}
</div>
);
Upvotes: 1
Reputation: 9448
Every time you call setState
, you overwrite the previous state. React tries to intelligently merge the provided (new) state and the previous state, but if there are any key collisions, the previous state (of that key) will be lost. If you want a list of items in your state, you'll have to do something like
let items = [];
for (...) {
items.push({
name: name,
id: result[0].id,
...
});
}
this.setState({ items: items });
following, you can access each item in the list by using this.state.items[someIndex]
etc
Upvotes: 4