Reputation: 123
I'm trying to make a workout log for myself and as a training for React and Node.js. I've got my own API with many functions, including one called "/get-workouts", which is, as the name says, to get workouts from the database.
Here's the API
app.get('/get-workouts', (req, res) => {
db('workoutlogger').select('*')
.limit(3)
.from('workouts')
.then(workouts => {
if(workouts.length) {
console.log(workouts);
res.status(200).json(workouts);
} else {
res.status(400).send('No workouts found');
}
})
.catch(err => {
console.log(err);
res.status(404).send('Error getting workouts')
})
})
Here's my frontend :
constructor(props) {
super(props)
this.state = {
workoutList: {}
}
}
getWorkouts = () => {
fetch('http://localhost:3001/get-workouts')
.then(workouts => {
workouts.json();
})
.then(workoutList => {
this.setState({workoutList})
})
.catch(err => console.log('There was an error getting workouts', err))
}
componentDidMount() {
this.getWorkouts();
}
If I console.log "workouts" in the first .then() of my fetch. My API clearly logs the list of the last 3 workouts I logged in, and initially, this.state.workoutList is an object. But once set.state supposedly set the workoutList to be a list of my workouts, it logs as undefined, and I can't display it. Where does the problem come from ?
Upvotes: 0
Views: 70
Reputation: 226
Arrow function needs to be understood correctly here.
Arrow function without curly braces implicitly returns whatever the next statement evaluates to. However, if you use curly braces, you are forming a block which is nothing but a list of statements (which evaluate to undefined
). Thus we need to use return
explicitly in that case.
constructor(props) {
super(props)
this.state = {
workoutList: {}
}
}
getWorkouts = () => {
fetch('http://localhost:3001/get-workouts')
.then(workouts => {
return workouts.json();
})
// above then fn can also be written (without curly braces) as below:
// .then(workouts => workouts.json()) -- removing curly braces returns result of statement implicitly
.then(workoutList => {
this.setState({workoutList})
})
.catch(err => console.log('There was an error getting workouts', err))
}
componentDidMount() {
this.getWorkouts();
}
Upvotes: 1
Reputation: 9063
You need to pass values between consecutive .then
s, they aren't implicitly passed. The return value of one .then
becomes the argument of the next. So do this:
.then(workouts => workouts.json())
.then(workoutList => {
this.setState({workoutList})
})
Removing the curly braces means it implicity returns workouts.json()
, which will then becomes the workoutList
argument in the next .then
Upvotes: 3