Reputation: 1355
I am learning React and I am trying to display a list of users from and ajax call. I am getting an unexpected token error from CodePen when I add the line
export default Users;
When I remove the line there are no more errors but the list of users is not being displayed.
My code:
function GetUsers(project){
$.ajax({
url: "https://jsonplaceholder.typicode.com/users",
success: function (data) {
console.log(data);
callback(null, data);
},
error: function (error) {
console.log(data);
callback(error, {});
}
});
}
function UserList(users) {
const userItems = users.map((user) =>
<ul>
<li>
{ user.name }
</li>
<li>
{ user.email }
</li>
<li>
{ user.phone}
</li>
</ul>
);
return (userItems);
}
class Users extends Component {
componentDidMount() {
GetUsers(null, function (err, data) {
if (err)
{
console.log(err);
}// do something
this.setState({ users: data })
}.bind(this))
}
render() {
return(
<UserList user = {this.state.users} />
);
}
}
if (document.getElementById('root')) {
ReactDOM.render(<Users />, document.getElementById('root'));
}
Here is my code.
Thank you for any and all help!
Upvotes: 0
Views: 89
Reputation: 2983
function GetUsers(project){
$.ajax({
url: "https://jsonplaceholder.typicode.com/users",
success: function (data) {
console.log(data);
callback(null, data);
},
error: function (error) {
console.log(data);
callback(error, {});
}
});
}
$.ajax
is asynchronous call, that means it doesn't returns directly any value (how it could if it is fetching the results from the internet) it Just creates another function which will call success
and error
when completed.
That's why we need to wrap it with callbacks
function GetUsers(project, resolve = () => {}, reject = () => {}) {
}
componentDidMount() {
GetUsers(null, function (err, data) {
if (err)
{
console.log(err);
}// do something
this.setState({ users: data })
}.bind(this))
}
This code is completely wrong, it has even syntax error so not worth to discuss it in details.
We need to call our new function and pass success callback for mutating the state
GetUsers(null, users => {
this.setState({ users });
});
In this way we will call GetUsers
wait for it's results and only after that we will mutate the state with new result
React component's don't have state by default, you need to infer the state from constructor so we need to change initialization to
constructor(props) {
super(props);
this.state = {
users: false
};
}
otherwise you will get Cannot call setState of undefined
as state is not automatically created for performance purposes and all components are Pure by default.
I have created a working sandbox here
Upvotes: 2
Reputation: 9448
in
function GetUsers(project){
$.ajax({
url: "https://jsonplaceholder.typicode.com/users",
success: function (data) {
return data;
},
error: function (error) {
console.log(error);
return {};
}
});
}
--
success: function (data) {
return data;
}
doesn't do what you think it does. return data
isn't really returning the data... anywhere.
You need to have a callback.
function GetUsers(project, callback){
$.ajax({
url: "https://jsonplaceholder.typicode.com/users",
success: function (data) {
callback(null, data)
},
error: function (error) {
callback(error, {})
}
});
}
class Users extends Component {
componentDidMount() {
GetUsers(null, function (err, data) {
if (err) // do something
this.setState({ users: data })
}.bind(this))
}
render() {
return(
<UserList user = {this.state.users} />
);
}
}
you can also Promise
-ify things to simplify the logic
Upvotes: 0