0

I am using React's componentDidMount to carry out ajax calls operations and based on the returned results setting data to react state variable.

Now I need to use the react state variable values by calling several different methods as I want to do the operations on page load but somehow it's not working. I have also tried timeout but it's not consistent.

Anyone have any idea, what's going wrong?

Here is some sample code:

componentDidMount() {

 Helper.GetReview1Data().then(data => {
            this.setState({
                review1data: data
            }) 

        })

  Helper.GetReview2Data().then(data=> {
            this.setState({
                review2data: data
            })
   })

 this.get1Data()
 this.get2Data()
}
get1Data = () => {

console.log(this.state.review1data.map(i=>i.name))
console.log(this.state.review2data.map(i=>i.name))

}
get2Data = () => {
console.log(this.state.review2data.map(i=>i.name))
}
Snehal Ramteke
  • 107
  • 1
  • 1
  • 7
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – jonrsharpe Sep 25 '19 at 09:59

4 Answers4

1

If the issue is that get1Data should only be called after the state has been set from both async operations, then perhaps you could wrap each operation in a promise that resolves after setState has completed, then use Promise.all() to call get1Data after both promises have resolved, like this:

componentDidMount() {

  const promise1 = new Promise(resolve => {
    Helper.GetReview1Data().then(data => {
      this.setState({
        review1data: data
      }, resolve)
    })
  })

  const promise2 = new Promise(resolve => {
    Helper.GetReview2Data().then(data => {
      this.setState({
        review1data: data
      }, resolve)
    })
  })

  Promise.all([promise1, promise2]).then(this.get1Data)
  promise2.then(this.get2Data)
}

get1Data = () => {
  console.log(this.state.review1data.map(i=>i.name))
  console.log(this.state.review2data.map(i=>i.name))
}

get2Data = () => {
  console.log(this.state.review2data.map(i=>i.name))
}
PeterN
  • 1,817
  • 2
  • 9
  • 12
0

As this.setState is asynchronous you can use the call back functions like this

componentDidMount() {

 Helper.GetReview1Data().then(data => {
            this.setState({
                review1data: data
            }, () => { this.get1Data()}) 

        })

Helper.GetReview2Data().then(data=> {
            this.setState({
                review2data: data
            }, () =>{this.get2Data()})
   }) 
}

get1Data = () => {
    console.log(this.state.review1data.map(i=>i.name))
}

get2Data = () => {
    console.log(this.state.review2data.map(i=>i.name))
}
Guruprasad
  • 753
  • 6
  • 23
  • Although callback works fine. If want to use data from both states i.e. `review1data` and `review2data` in one method for e.g. `get1data ()` it doesn't. – Snehal Ramteke Sep 25 '19 at 10:22
  • To clarify more I want to use something like this `get1Data = () => { console.log(this.state.review1data.map(i=>i.name)) console.log(this.state.review2data.map(i=>i.name)) }` – Snehal Ramteke Sep 25 '19 at 10:23
  • As you are using both the functions in `componentDidMount`, both the functions data will be available after the render, where do you want those data exactly ? let me tell you the data you want is available at every other functions after `componentDidMount` – Guruprasad Sep 25 '19 at 10:29
  • The data should be available after `componentDidMount` but when I am using state data `review1data` and `review2data` in single method e.g. `get1data ()` which is outside of `componentDidMount` but called on `componentDidMount` it sometimes work and sometimes doesn't. As I want to use the data on page load I am calling method `get1data()` on `componentDidMount` – Snehal Ramteke Sep 25 '19 at 10:44
0

the issue stems from the fact that Helper.GetReview1Data() and this.setState({review1data: data}) are asynchronous functions, but you are calling this.get1Data() synchronously afterwards. This means the console.log will execute before you receive a response and set your state.

Try placing this.get1Data() as a callback after you have set your state like so:

 Helper.GetReview1Data().then(data => {
        this.setState({
            review1data: data
        }, this.get1Data) 

    })
0

use setState({},()=>action when to do when it change state ) that will be executed after the setstate update the state as this shape

 Helper.GetReview1Data().then(data => {
        this.setState({
            review1data: data
        }, this.get1Data) 

    })
Mohammed Al-Reai
  • 2,344
  • 14
  • 18