0

How do I get the value of the failed array outside of the function? Because I need this array as an input for other functions.

failed = [];
async function fetchFromApi(i) {

    var ApiEndpoint = "https://jsonplaceholder.typicode.com/todos/" + i
    var httpRequest = {
        method: "GET"
    }


    var response = await fetch(ApiEndpoint, httpRequest);
    if (!response.ok) { // Necessary for error handling, fetch does not return an error if HTTP request fails

        failed.push(i);
        console.log(failed)

    } else {
        let symbolData = await response.json();

        console.log(JSON.stringify(symbolData))
        return JSON.stringify(symbolData);
    }

};
    
fetchFromApi("abc")
console.log(failed)

The console.log("failed") in the code above gives me an empty array []. I want it to be getting ["abc"] when this variable being called outside of the function

UPDATE EDIT (new follow-up question):

I tried @SlothOverlord 's solution and it seems to work below is the example.

const myFunction = async (j) => {  
  failed = [];
  async function fetchFromApi(i) {

      var ApiEndpoint = "https://jsonplaceholder.typicode.com/todos/" + i
      var httpRequest = {
          method: "GET"
      }


      var response = await fetch(ApiEndpoint, httpRequest);
      if (!response.ok) { // Necessary for error handling, fetch does not return an error if HTTP request fails

          failed.push(i);

      } else {
          let symbolData = await response.json();

          console.log(JSON.stringify(symbolData))
          return JSON.stringify(symbolData);
      }

  };
 
  await fetchFromApi(j)
  return failed
}

myFunction("abc").then(data=>console.log(failed))

However, when I add in a forEach statement within the function, it breaks and returns an empty array again. See example below. What's going on here?

const myFunction = async (j) => {  
  failed = [];
  async function fetchFromApi(arrays) {

    arrays.forEach(async function(i) {


    var ApiEndpoint = "https://jsonplaceholder.typicode.com/todos/" + i
    var httpRequest = {
      method: "GET"
    }


    var response = await fetch(ApiEndpoint, httpRequest);
    if (!response.ok) { // Necessary for error handling, fetch does not return an error if HTTP request fails

      failed.push(i);
      // console.log(failed)

    } else {
      let symbolData = await response.json();

      console.log(JSON.stringify(symbolData))
      return JSON.stringify(symbolData);
    }
    
    });
 

}
  await fetchFromApi(j)
  // console.log(failed)
  return failed
}

myFunction(["aaa", "abc"]).then(data=>console.log(failed))
Sun Tianyi
  • 93
  • 1
  • 6

2 Answers2

1

You need to await the fetchFromApi("abc") function.

Async await only works INSIDE the function, not outside of it.

So what happened is:

fetchFromApi("abc") is called
console.log(failed) is empty
fetchFromApi("abc") finished

The solution is to wrap the function in async and await the fetchFromApi call

const myFunction = async () => {
//...

failed = [];
async function fetchFromApi(i) {
//...
}


await fetchFromApi("abc")
console.log(failed)
}
SlothOverlord
  • 1,655
  • 1
  • 6
  • 16
  • Hi SolthOverlord, thanks for the suggestion, I tried and raised another follow-up question in my original post. Do you have an idea? Thanks in advance! – Sun Tianyi Nov 10 '21 at 15:39
  • Hi, I don't have that much experience in async await in loops. You might want to search stack overflow for "forEach async await". https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop – SlothOverlord Nov 11 '21 at 07:31
1

fetchFromApi is an async method, you need to await it if you want to see it's result logged.

JavaScript has a concurrency model based on an event loop, which is responsible for executing the code, collecting and processing events. when the async call will have it's result it will be placed in the callback queue and on the next iteration (tick), it will be popped out from there and placed in the execution stack to be processed. when you use await, the exection call will be halted at that point and will progress until the async call has it's result.

failed = [];
async function fetchFromApi(i) {

    var ApiEndpoint = "https://jsonplaceholder.typicode.com/todos/" + i
    var httpRequest = {
        method: "GET"
    }


    var response = await fetch(ApiEndpoint, httpRequest);
    if (!response.ok) { // Necessary for error handling, fetch does not return an error if HTTP request fails

        failed.push(i);
        console.log(failed)

    } else {
        let symbolData = await response.json();

        console.log(JSON.stringify(symbolData))
        return JSON.stringify(symbolData);
    }

};
    
await fetchFromApi("abc")
console.log(failed)

JS event loop - https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

Ran Turner
  • 14,906
  • 5
  • 47
  • 53
  • The issue with this solution is "await is only valid in async", so I tried @SlothOverlord 's solution by wrapping the function `fetchFromApi` inside another async function , however, I came across another issue, I updated in my original post, do you have an idea? Thanks in advance! – Sun Tianyi Nov 10 '21 at 15:40