0

How can I properly make the following POST request?

const postWorkout = async () => {

    setCompletedWorkout({
      date: 31,
      day: workout.mains[0].day,
      exercises: completedExercises
    })
    
    try {
      await axios.post('/history', completedWorkout)
    } catch(error) {
      throw error
    }
  }

I believe that it makes the request before completedWorkout is actually set as shown in the DB by an empty document: Empty document in MongoDB after POST request

nalanart
  • 41
  • 6
  • Do you want to make the request after updating `completedWorkout`? – QuazBuzz Nov 17 '20 at 20:45
  • 1
    State updates do not happen immediately. `completedWorkout` is a const (or should be), and is not capable of changing until the function is called **next render**. You would either need to move the post into a `useEffect` or use the new object directly. – Brian Thompson Nov 17 '20 at 20:48
  • Yes I do! The only workaround I've tried so far is to have them in different functions and calling the setCompletedWorkout function first then calling the function to make a request. However, this is probably not the most efficient way... I'd like for them to be in the same function – nalanart Nov 17 '20 at 20:49

1 Answers1

2

I'm assuming setCompletedWorkout is setting it to the state. If so, you will need to wait for that to be completed since setting a state is async. You can do this by using useEffect like so:

useEffect(() => {
   // POST HERE
}, [completedWorkout]);

The code inside useEffect will execute once your completedWorkout is set

Sacha
  • 322
  • 1
  • 8
  • Thanks! I already have a useEffect in place that gets data on the first render. Is it possible to have multiple useEffects or just one? – nalanart Nov 17 '20 at 20:53
  • 2
    There's no limit to the number of `useEffects` you can have. – Brian Thompson Nov 17 '20 at 20:54
  • Is there a way for the useEffect to be invoked ONLY when the workout is set? I have my dependency array as [workout] but according some documentation, it is being invoked on the first render as well? So it actually posts twice, once when it is first rendered and then a second time when setWorkout is called – nalanart Nov 17 '20 at 22:14
  • @nalanart inside the useEffect, maybe you could add a check to make sure completedWorkout is not empty/null – Sacha Nov 19 '20 at 00:01