4

I'm trying to utilize async/await in my React app. From what I've been reading in this code the function should run first and then the console.log will wait for the function to finish...

async postSelectedHandler() {
    await this.getInServiceVenues();
    console.log('Updated In Service 2: '+this.state.venuesInService);
}

Maybe I'm wrong but what I'm trying to do is make sure the function runs first before the console.log runs but it's still running asynchronously.

Code for getInServiceVenues...

getInServiceVenues = () =>{
    this.setState({ loading: true });
    let bodyInService = [];
    let iterationInService = 0;
    let RequestingNetworkOperatorList = [];
    let updatedVenuesInService = [];
    
    axios.post( '/propertymanagement/listVenues', bodyInService, 
    {
        headers: {}
    })
        .then( response => {
            if (this._isMounted) {
            this.setState({loading: false});
            this.setState({venues: []});
            const venuesInService = response.data.InServiceVenueList;
            let venueIdInService = null;
            
            bodyInService.push(venuesInService);
            
            bodyInService.forEach(val=>{
                    venueIdInService = Object.keys(bodyInService[0]);
                    //console.log(venueId);
                })
            if(this.state.venuesInService!==[]){
                    this.setState({venuesInService:[]});
                }
            venueIdInService.forEach(val=>{
                
                updatedVenuesInService = bodyInService.map(venueInService => {
                    return {
                        ...venueInService[venueIdInService[iterationInService]],
                        iterationInService,
                        RequestingNetworkOperatorList
                    }

                });
                
                this.setState({
                    venuesInService:[...this.state.venuesInService, updatedVenuesInService]
                });
                iterationInService = iterationInService + 1;
                
            })
            console.log('Updated In Service 1: '+this.state.venuesInService);
        }} )
        .catch(error => {
            console.log(error);
            this.setState({error: true});
        });
    }
Mohan Rajput
  • 634
  • 9
  • 21
Dave D
  • 41
  • 1
  • 7
  • 2
    does that geInServiceVenues() return a promise? can we see the code of that function – Menawer Aug 20 '20 at 13:32
  • 3
    can you show the code for getInServiceVenues? – Trevor Aug 20 '20 at 13:32
  • 2
    Your code will wait for whatever promise returned in `getInServiceVenues()` to complete and then run the `console.log`. Then `postSelectedHandler` will complete – possum Aug 20 '20 at 13:32
  • Post has been updated with code for getInServiceVenues() – Dave D Aug 20 '20 at 13:35
  • 1
    await only works if the function you call returns a promise – gbalduzzi Aug 20 '20 at 13:35
  • 1
    Your `getInServiceVenues` does not return a promise, that's why it is not working – gbalduzzi Aug 20 '20 at 13:35
  • If you await something that isn't a promise, such as a function that doesn't return a promise, you'll find that whenever the value of the expression following the await operator is not a Promise, it gets converted to a **resolved Promise**. Meaning it won't do something pathological like wait forever for something that will never happen, it'll just continue past the _await_. – Wyck Aug 20 '20 at 13:45
  • Does this answer your question? [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Heretic Monkey Aug 20 '20 at 14:37

2 Answers2

1

The problem is, the function you are calling isn't returning a promise so that bit is essentially running synchronously.

Add a return to the beginning of this line:

axios.post( '/propertymanagement/listVenues', bodyInService, 

and it should work.

You can also optionally convert it to use async and await too, which is functionally the same:

getInServiceVenues = async () =>{
    this.setState({ loading: true });
    let bodyInService = [];
    let iterationInService = 0;
    let RequestingNetworkOperatorList = [];
    let updatedVenuesInService = [];
    
    try {
      const response = await axios.post( '/propertymanagement/listVenues', bodyInService, 
      {
          headers: {}
      });
    
      // everything from your then()
    } catch (error) {
      // everything from your catch()
    }
}    
samanime
  • 25,408
  • 15
  • 90
  • 139
0

You should use await/async in you getInServiceVenues function, change the then and catch to a synchronous operation.

Instead of using then and catch, use try/catch block and return the result of axios and then you dont need to use async/await outside this function.

Something like the code below

getInServiceVenues = async () =>{
    this.setState({ loading: true });
    let bodyInService = [];
    let iterationInService = 0;
    let RequestingNetworkOperatorList = [];
    let updatedVenuesInService = [];
    
    try { 
        const result = axios.post( '/propertymanagement/listVenues', 
        bodyInService, {headers: {}})     
        if (this._isMounted) {
            this.setState({loading: false});
            this.setState({venues: []});
            const venuesInService = response.data.InServiceVenueList;
            let venueIdInService = null;
            
            bodyInService.push(venuesInService);
            
            bodyInService.forEach(val=>{
                    venueIdInService = Object.keys(bodyInService[0]);
                    //console.log(venueId);
            })

            if(this.state.venuesInService!==[]){
                    this.setState({venuesInService:[]});
            }
            venueIdInService.forEach(val => {
                updatedVenuesInService = bodyInService.map(
                  venueInService => {
                    return {
                        ...venueInService[
                            venueIdInService[iterationInService]
                        ],
                        iterationInService,
                        RequestingNetworkOperatorList
                    }
             });
                
                this.setState({
                    venuesInService:[...this.state.venuesInService, updatedVenuesInService]
                });
                iterationInService = iterationInService + 1;
                
            })
            console.log('Updated In Service 1:'+this.state.venuesInService);
    } catch(error) {
        console.log(error);
        this.setState({error: true});
    };
}