0

I'm relatively new to this and don't understand why this error is happening. I am trying to call an axios post request to access a database and let a user login, but the promise is not acting as expected. It will access the database and give back an object, but whenever I try to assign "result" below, it says result is still an empty object with a __proto__ object inside, even though console.log(result) will print out the data I want. How can I get the data I need into the "result" object instead of it just being an empty variable?

I've attached my code here:

        const userlogin = {
            company: this.state.company,
            email: this.state.email,
            password: this.state.password            
        }
        let result = {}
        axios.post('http://localhost:5000/login', userlogin)
            .then(res => {
                console.log(res.data[0])
                result = res.data[0]
            })
            .catch(res => {
                console.log("Failed")
            })
        
        console.log(result)
        window.location = '/'

Printing res.data[0] prints exactly what I want, but when I assign it to the result and print result, it displays an empty object with the __proto__. I've been struggling with this for a while, and any help would be greatly appreciated! Thank you so much!

Luke
  • 3
  • 1

2 Answers2

0

axios.post().then() is non-blocking and asynchronous. That means the the axios request is initiated and then the code after it runs (which includes your console.log()). Then, sometime later, the axios operation completes, the promise resolves and then .then() handler is called.

Therefore, your console.log(result) runs BEFORE you assign the value to it. The callback to .then() gets called sometime later so you're trying to look at the result before it has been assigned.

The proper solution here is to use the result INSIDE the .then() handler or call some function from there and pass the value to that function. You cannot reliably use the value outside the .then() handler because you don't know when it's actually been set.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

this accomplishes what you described

// using async/await (modern syntax)
const myFunc = async () => {
  try {
    const userlogin = {
      company: this.state.company,
      email: this.state.email,
      password: this.state.password
    }
    let result = {}
    const res = await axios.post('http://localhost:5000/login', userlogin)
    console.log(res.data[0])
    result = res.data[0]
    console.log(result)
    window.location = '/'
  } catch (err) {
    console.log('Failed')
  }
}

// using nested syntax (old syntax)
const myFunc2 = () => {
  const userlogin = {
    company: this.state.company,
    email: this.state.email,
    password: this.state.password
  }
  let result = {}
  axios.post('http://localhost:5000/login', userlogin)
    .then(res => {
      console.log(res.data[0])
      result = res.data[0]
      console.log(result)
      window.location = '/'
    })
    .catch(err => {
      console.log("Failed")
    })
}

the main issue is that axios returns a promise, so anything not nested inside .then gets executed immediately. Using the modern syntax makes it easier to know that we are waiting for the response back from our target. Using the older syntax can get confusing especially if there are multiple requests to a backend that have to be executed.

alilland
  • 2,039
  • 1
  • 21
  • 42