Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set a timeout to abort an $http.get() inside a factory or service?

I have the following method getData(url) in a my factory which uses $http.get(url) to get data from an URL

angular
  .module('az-app')
  .factory('WebServiceFactory', function ($http, $q) {

   var WebServiceFactory = this;


   WebServiceFactory.getData = function (url) {

      var deferred = $q.defer();

      $http.get(url)
        .then(
        function (response) {

          deferred.resolve({
            data: response
          });

        }, function (rejected) {

          deferred.reject({
            data: rejected
          });
        }
      );
      //Promise to be returned
      return deferred.promise;
    }

It works fine but I need to abort the http.get and/or reject the promise so I can display an error message from my controller which has this method:

var getSpecialties = function (type) {
  doctorsCtrl.showLoading();

  var url = "example.com";

  WebServiceFactory.getData(url)
    .then(
    function (result) {
      doctorsCtrl.hideLoading();


      var specialtiesArray = result.data.data;

      StorageFactory.specialties = specialtiesArray;
      doctorsCtrl.specialties = StorageFactory.specialties

      //I WANT TO TRIGGER THIS REJECTED FUNCTION when timeout time is finished
    }, function (rejected) {
      doctorsCtrl.hideLoading();
      doctorsCtrl.showAlert();
    }
  );
}
like image 632
Jeka Avatar asked Oct 20 '15 19:10

Jeka


People also ask

How do I set http timeout?

Stanza entries for timeout settings are usually located in the [server] stanza of the WebSEAL configuration file. After the initial connection handshake has occurred, this stanza entry specifies how long WebSEAL holds the connection open for the initial HTTP or HTTPS request. The default value is 120 seconds.

What is HTTP connection timeout?

The HyperText Transfer Protocol (HTTP) 408 Request Timeout response status code means that the server would like to shut down this unused connection. It is sent on an idle connection by some servers, even without any previous request by the client.

What is the function of the $timeout service?

The '$timeout' service of AngularJS is functionally similar to the 'window. setTimeout' object of vanilla JavaScript. This service allows the developer to set some time delay before the execution of the function.


1 Answers

The service $http accepts, in the config object, a timeout property that answers to what you need. Have a look at the documentation, especially the part about the config object:

timeout – {number|Promise} – timeout in milliseconds, or promise that should abort the request when resolved.

Also, notice that you're using promises in an inefficient way. The following is a promise antipattern:

WebServiceFactory.getData = function (url) {

 var deferred = $q.defer();

 $http.get(url)
   .then(
   function (response) {

     deferred.resolve(...);

   }, function (rejected) {

     deferred.reject(...);
   }
 );
 //Promise to be returned
 return deferred.promise;
}

You could have simply:

WebServiceFactory.getData = function (url) {
    return $http.get(url);
}

With a timeout of 3 seconds it would be:

Service:

WebServiceFactory.getData = function (url) {
    return $http.get(url, {timeout: 3000});  // <-- timeout applies ONLY for this call
}

Controller:

WebServiceFactory.getData(url).then(
    function (result) {
      doctorsCtrl.hideLoading();
      doctorsCtrl.specialties = StorageFactory.specialties = result.data;
    }, function (rejected) {
      doctorsCtrl.hideLoading();
      doctorsCtrl.showAlert();
    }
  );

Notice also that you're calling hideLoading both in case of success and error. You can call it once, in a chained finally handler:

// ...
.finally(function () {
    doctorsCtrl.hideLoading();
}
like image 97
Michael P. Bazos Avatar answered Sep 22 '22 12:09

Michael P. Bazos