Reputation: 321
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
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
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
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
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