6

The question is, how can I get rid of calling second fetch 300 times? Or is there another way to do that, what I`m doing? Additionally how to do ordered(don`t wanna sort) calls of first api, because they`re coming from api in chaotic asynchronous way?

for(let i=1;i<=300; i++) {
  fetch(`example.api/incomes/${i}`)   // should be returned 300 times
    .then(response => {
      if(response.ok) return response.json();
      throw new Error(response.statusText);
    })
    .then(function handleData(data) {
        return fetch('example.api')   // should be returned 1 time
        .then(response => {
            if(response.ok) return response.json();
            throw new Error(response.statusText);
          })
    })
    .catch(function handleError(error) {
        console.log("Error" +error);            
    }); 
};
4
  • So you want to call the first fetch 300 times, then after all fetches are finished, call the second one? Commented Mar 16, 2020 at 17:23
  • If you have control over the API, I would suggest you to implement some sort of batching mechanism. 300 API calls will just slow down whatever you're doing and overload your API server. Commented Mar 16, 2020 at 17:23
  • Yup, and they should have access to retrieve data of each other. First fetch is a 300 objects that are should be bonded corresponding to ID of an items in array of second fetch. Commented Mar 16, 2020 at 17:29
  • @MaazSyedAdeeb its like same API, but each item lays down under different api adress. So im using {i} parameter to have access to it. Commented Mar 16, 2020 at 17:31

3 Answers 3

17

You can solve it using Promise all.

let promises = [];
for (let i = 1; i <= 300; i++) {
  promises.push(fetch(`example.api/incomes/${i}`));
}
Promise.all(promises)
  .then(function handleData(data) {
    return fetch("example.api") // should be returned 1 time
      .then(response => {
        if (response.ok) return response.json();
        throw new Error(response.statusText);
      });
  })
  .catch(function handleError(error) {
    console.log("Error" + error);
  });
Sign up to request clarification or add additional context in comments.

2 Comments

I want to grab my GH repos api.github.com/users/tik9/repos with Promise and then do a fetch to another api to change the ISO Date to another date format. But Promise does not work, I get TypeError: response.json is not a function with promises =[];promises.push(fetch(github));Promise.all(promises).then((response) => response.json())
Promise.all will return array of response, you need to loop. Promise.all(promises).then((responses) => responses.map(r => .json()))
2

The other answers are perfectly valid, but a bit outdated. Here is a new way of doing it with async/await:

async function repeat(uri, amount) {
    const result = []
    for (let i = 1; i <= amount; i++) {
        const response = await fetch(`${uri}/${i}`) // waits for the response
        const data = await response.json()
        result.push(...data)
    }

    return data
}

repeat('example.api/incomes', 300)
    .then(handleData) // defined elsewhere or anonymous
    .catch(handleError) // defined elsewhere or anonymous
}

If you don't know about this, async/await is basically a clearer way to write promises.

The async function declaration creates a binding of a new async function to a given name. The await keyword is permitted within the function body, enabling asynchronous, promise-based behavior to be written in a cleaner style and avoiding the need to explicitly configure promise chains.

(Source)

Comments

0

Store all of your requests in an array. Then use Promise.all() the wait for all of those requests to finish. Then when all of the requests are finished, use another Promise.all() with a map() inside of it to return the the JSON of each request and wait for all of those to finish.

Now your data argument will have an array of objects available in the next then callback.

function fetch300Times() {
  let responses = [];
  for(let i = 1; i <= 300; i++) {.
    let response = fetch(`example.api/incomes/${i}`);
    responses.push(response);
  } 
  return Promise.all(responses);
}

const awaitJson = (response) => Promise.all(responses.map(response => {
  if(response.ok) return response.json();
  throw new Error(response.statusText);
}));

fetch300Times()
  .then(awaitJson)
  .then(data => {
    fetch('example.api')   // should be returned 1 time
      .then(response => {
        if(response.ok) return response.json();
        throw new Error(response.statusText);
      });
  }).catch(function handleError(error) {
    console.log("Error" +error);            
  });  

Comments

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.