Chirag Jain
Chirag Jain

Reputation: 321

How to wait for an API response for maximum 15 seconds in react

I have an API which sometimes does not return a response because of some dependencies. I need to wait for maximum 15 seconds for the response, if I don't receive any response within 15 seconds, I want to skip it and make the control goes to next line to execute next set of instructions. This is how I have the API call:

const fetchData = async () => {
  const response = await getData() // I want to await max 15 seconds here, if not next line should be executed 
  
  const response2 = await getSecondData()
}

How can I implement the same in react ?

Upvotes: 2

Views: 6064

Answers (4)

Zahir Masoodi
Zahir Masoodi

Reputation: 858

Fetch API

const TIMEOUT = 15000; // Set timeout to 15 seconds

function fetchAPI(url, options) {
  const controller = new AbortController();
  const { signal } = controller;

  const timeoutId = setTimeout(() => {
    controller.abort();
  }, TIMEOUT);

  return fetch(yourBaseURL, { ...options, signal })
    .then((response) => {
      clearTimeout(timeoutId);
      return response;
    })
    .catch((error) => {
      clearTimeout(timeoutId);
      throw error;
    });
}

//Usage
fetchAPI('yourBaseURL', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json'
  }
})
.then((response) => {
  // handle the response
})
.catch((error) => {
  // handle the error
});

Axios

//Base API
this.httpService = axios.create({
    baseURL: `yourBaseURL`,
    headers: headers,
    timeout: 15000, // 15 seconds
    timeoutErrorMessage: "Request timed out. Please try again later.",
});

//standalone
axios.get('yourBaseURL', { timeout: 15000 })

Upvotes: 0

ndotie
ndotie

Reputation: 2160

@steve K deleted this answer, but i think its really cool answer, i prefer to repost it for literature purposes, because its a really great answer

const promiseTimeout = new Promise((resolve) => (setTimeout(() => resolve(false),  15000)))

const fetchData = async () => {
  const response = await Promise.race([promiseTimeout, getData()]) // I want to await max 15 seconds here, if not next line should be executed 
  
  // You can do a check here if you need to
  if(!response) // do something 

  const response2 = await getSecondData()
}

Upvotes: 1

ndotie
ndotie

Reputation: 2160

waiting for 15 seconds then execute another function is not a react feature but just pure javascript.

const timer15sec = new Promise((resolve, reject) => {
  setTimeout(resolve, 1500, 'overtime');
});
const firstCall =  getData();

Promise.race([timer15sec , firstCall ]).then(async (value) => {
  let response;
  if(value === 'overtime') { //means timer exceeded 15secs
      response = await getSecondData()
  }else { //not exceeded 15secs
      response = value
  }
 return  response
}).then(result => {
   //you can have your result here!!
});

Upvotes: 0

Kanishk Anand
Kanishk Anand

Reputation: 1702

You can wrap the getData in a function that has the timeout set, and if it doesn't resolve within than time, than throw error.

function timeoutPromise(fn, timeout) {
 return new Promise((resolve, reject) => {
    // reject if timeout happens
    setTimeout(() => { 
         reject('API_TIMEOUT');
    }, timeout);
    // handle the promise appropriately 
    fn().then((data) => resolve(data)).catch((err) => reject(err));
 })
}

Inside your code, you can do the following:

const fetchData = async () => {
  try {
     const response = await timeoutPromise(getData, 15000) // I want to await max 15 seconds here, if not next line should be executed 
  } catch(e) {
    // handle error
  }
  const response2 = await getSecondData()
}

This will work for Promises in general, but won't do things like cancel API call, meaning, if API times out, the server call won't be cancelled from browser.

Upvotes: 0

Related Questions