Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use setTimeout to break a fetch request in react native?

Tags:

react-native

I'm trying to get some data from a server with fetch request. Some times network will fail or similar other things happens and I want to have a timeout to prevent further errors and also have a better experience.

Actually I want to wait for 20 seconds and if I don't get any response I want to show an error and also break the fetch request.

I have a loading modal which I can close it by timeout but I want to break the fetch request either.

here is my fetch request code:

_testPress = async () => { 
        //setTimeout(() => {this.setState({loading: false})}, 20000)
        this.setState({loading : true})
        fetch(getInitUrl('loginUser'), {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({          
          password : this.state.password,
          email : this.state.emailAddress,            
        }),
      }).then(response => Promise.all([response.ok, response.status ,response.json()]))
      .then(([responseOk,responseStatus, body]) => {        
        if (responseOk) {
          //console.log(responseOk, body);
          this._signInAsync(body.token);
          // handle success case
        } else {
          console.log(responseStatus);
          this.setState({
            showAlert : true,
            alertType : true,
            alertMessage : body.message
          });
        }
      })
      .catch(error => {
        console.error(error);
        // catches error case and if fetch itself rejects
      });
      }

I used setTimeout to close loading module but it wont stop actual request which I want it to stop after 20 seconds.

Please help me with your advice. thx.

like image 295
Pouya92 Avatar asked Dec 29 '25 09:12

Pouya92


2 Answers

There is no standard param you can add to fetch, but you can do this work around:

// creating a wrapper for promises
function timeout(milliseconds, promise) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(new Error("timeout exceeded"))
    }, milliseconds)
    promise.then(resolve, reject)
  })
}

// using that wrapper with fetch
timeout(1000, fetch('/api'))
  .then(function(response) {
     // response success
}).catch(function(error) {
  // timeout error or server error
})

EXAMPLES:

Timeout exceeded:

// creating a wrapper for promises
function timeout(milliseconds, promise) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject(new Error("timeout exceeded"))
        }, milliseconds);

        promise.then(resolve, reject);
    });
}
  
const requestErr = new Promise((resolve, reject) => {
    setTimeout(() => {
        // request finished.
        resolve();
    }, 2500);
})

timeout(1000, requestErr)
    .then(function(response) {
        console.log("OK!");
    }).catch(function(error) {
        console.log("ERROR TIMEOUT!");
    });

Timeout not exceeded:

// creating a wrapper for promises
function timeout(milliseconds, promise) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject(new Error("timeout exceeded"))
        }, milliseconds);

        promise.then(resolve, reject);
    });
}

const requestOk = new Promise((resolve, reject) => {
    setTimeout(() => {
        // request finished.
        resolve();
    }, 500);
})

timeout(1000, requestOk)
    .then(function(response) {
        console.log("OK!");
    }).catch(function(error) {
        console.log("ERROR TIMEOUT!");
    });

You can also use AXIOS that has its own timeout setting.

like image 173
JoKeRxbLaCk Avatar answered Dec 31 '25 00:12

JoKeRxbLaCk


You can abort fetch request by passing "signal" into fetch options.

An AbortSignal object instance; allows you to communicate with a fetch request and abort it if desired via an AbortController.

https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch

Full code example is here.

https://javascript.info/fetch-abort

let controller = new AbortController();
fetch(url, {
  signal: controller.signal
});

controller.abort();
like image 38
Hidan Jamanako Avatar answered Dec 30 '25 23:12

Hidan Jamanako



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!