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

mayankmehtani
  • 435
  • 4
  • 14
  • 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. – sibasishm Oct 31 '19 at 05:17
  • If I need to access the array values instantly what would the best way to proceed be – mayankmehtani Oct 31 '19 at 05: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. – sibasishm Oct 31 '19 at 05: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. – Neha Sharma Oct 31 '19 at 05:23
  • `await call_vstat ()` – Daniel Lizik Oct 31 '19 at 05:23
  • var result = await call_vstat(devices[i], my_token); results.push(result); [dont use then] – Sahil Pasricha Oct 31 '19 at 05:24
  • 1
    Have a look on this [Link](https://stackoverflow.com/questions/42260524/array-length-is-zero-but-the-array-has-elements-in-it). Answer by ibrahim mahrir – Hamza Chaudhary Oct 31 '19 at 05:25

2 Answers2

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

Karthik
  • 1,332
  • 1
  • 12
  • 21
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
    }
sibasishm
  • 443
  • 6
  • 24
  • Why do we need to use promises and async together unnecessarily. A simple await inside the for loop fixes the issue – Karthik Oct 31 '19 at 07:32
  • 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: https://stackoverflow.com/questions/38180080/when-to-use-promise-all – sibasishm Oct 31 '19 at 07:42
  • 1
    But If one of the promises fail the whole thing fails. – Karthik Oct 31 '19 at 07:54