0

Trying to get values from an API using async functions. I need to be able to access the values in the array immediately.

componentDidMount() {
    var devices = this.props.navigation.state.params.userInfoState.deviceIds

    async function call_vstat(device, token)  {
        try {
          let response = await fetch(
            'http://app.yatis.io/api/admin/getDeviceStatus?api_access_token=' + token + '&deviceId=' + device,
          );
          let responseJson = await response.json();
          return responseJson;
        } catch (error) {
          console.error(error);
        }
    }


    var results = []
    for (i = 0; i < devices.length; i++) {
        var result = call_vstat(devices[i], my_token)
        .then( (result) => (results.push(result) ) )
    }

    console.log(results.length)
    console.log(results)
}

Here's the issue when I look at the logger, I get an array of length twenty one but when logging the length itself it shows zero.enter image description here

7
  • 1
    Carefully observe the tiny i button next to your array which symbolizes that your array value is evaluated later. Which is obvious due to the async behavior. Commented Oct 31, 2019 at 5:17
  • If I need to access the array values instantly what would the best way to proceed be Commented Oct 31, 2019 at 5:18
  • Make an array of promises with looping over devices.length and push call_vstat(devices[i], my_token). Then resolve them together with Promise.all(). Let me know if this solves your issue. Commented Oct 31, 2019 at 5:22
  • 1
    As Mentioned by Sibasish, this due to async behavior. You can add a check for array.length once it is more than 0 then do the required business logic. Commented Oct 31, 2019 at 5:23
  • 1
    Have a look on this Link. Answer by ibrahim mahrir Commented Oct 31, 2019 at 5:25

2 Answers 2

1

If you are using async await you don't have to use the then(). What you can do is

for (i = 0; i < devices.length; i++) {
    var result = await call_vstat(devices[i], my_token)
    results.push(result) 
}

Hope this works

Sign up to request clarification or add additional context in comments.

3 Comments

isn't this a bit slow though?
Why is it slow?
you'll have to wait for each call to be made one by one
0

As mentioned in my comments,

    var promiseArray = [];
    for (i = 0; i < devices.length; i++) {
        promiseArray.push(call_vstat(devices[i], my_token));
    }

    var results = await Promise.all(promiseArray);

    if (results.length > 0) {
        //perform your business logic after this check to avoid any errors
    }

3 Comments

Why do we need to use promises and async together unnecessarily. A simple await inside the for loop fixes the issue
Since all the requests are similar, I prefer resolving them at once. There are many ways to handle the problem. I can't find proper documentation on where to use Promise.all() but the1st answer on this thread might help you settle: stackoverflow.com/questions/38180080/when-to-use-promise-all
But If one of the promises fail the whole thing fails.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.