Vaggouras
Vaggouras

Reputation: 59

Why function is not running before rest of the code in React App

It's probably because of my half-knowledge on this but I don't know how to fix it:

Basically I have the following:

  1. A button "Check numbers"
<Button fullWidth
                variant="contained"
                onClick={this.checkOptOut}
                margin="normal"
                component="label"
              >
  1. Upon clicking, the function checkOptOut is called
checkOptOut = (event) => {
    event.preventDefault()
    this.getOptOutList()
    this.checkNumbers()
  }

So basically what I expect is that getOptOutList gets called first. It looks like this

getOptOutList = () => {
    fetch(`${global.config.url}get-optout-list`, {
      method: "POST",
      headers: {
        'Content-Type': 'application/json',
        'Authorization': this.state.auth_header
      }
    })
      .then((res) => res.json())
      .then((data) => {
        console.log(`Checked optout list: ${JSON.stringify(data)}`)

        if(data.data.optOutNumbers.length > 0){
          this.setState({}, () => {
            this.setState({
              optOutNumbers: data.data.optOutNumbers
            })   
          })
          return;
        }
      })
      .catch((error) => {
        console.log(error);
        return;
      });
  }

And then this.checkNumbers() has in the beginning:

checkNumbers(){
    //event.preventDefault();


    //this.getOptOutList()
    
    console.log(`Opt out list length: ${this.state.optOutNumbers.length}`)

...
OTHER STUFF

I notice that ALWAYS checkNumbers seems to be called/finished first so in the logs I always get Opt out list length : 0

And after that I get the logs of the previous function.

How can I ensure I first run getOptOutList, save the state, and then run checkNumbers?

Upvotes: 0

Views: 102

Answers (1)

Felix
Felix

Reputation: 2691

The fetch function is an asynchronous call. Therefore it is executed in the background and will return immediately.

You can use the Promise returning from it to wait for it's completeness:


getOptOutList = () => {
    // fetch is async and should be returned
   return fetch(`${global.config.url}get-optout-list`, {
      method: "POST",
      headers: {
        'Content-Type': 'application/json',
        'Authorization': this.state.auth_header
      }
    })
      .then((res) => res.json())
      .then((data) => {
        console.log(`Checked optout list: ${JSON.stringify(data)}`)

        if(data.data.optOutNumbers.length > 0){
          this.setState({}, () => {
            this.setState({
              optOutNumbers: data.data.optOutNumbers
            })   
          })
          return;
        }
      })
      .catch((error) => {
        console.log(error);
        return;
      });
  }

checkOptOut = (event) => {
    event.preventDefault()
    this.getOptOutList()
        .then(() => this.checkNumbers())

  }

Upvotes: 1

Related Questions