Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Aborting AJAX Requests Using $http And AngularJS

View abort-angularjs.htm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
<!doctype html>
<html ng-app="Demo">
<head>
<meta charset="utf-8" />
 
<title>
Aborting AJAX Requests Using $http And AngularJS
</title>
 
<style type="text/css">
a[ ng-click ] {
color: red ;
cursor: pointer ;
text-decoration: underline ;
}
</style>
</head>
<body ng-controller="DemoController">
 
<h1>
Aborting AJAX Requests Using $http And AngularJS
</h1>
 
<p>
<a ng-click="loadData()">Load Data</a> -
<a ng-click="abortRequest()">Abort Request</a>
</p>
 
<!-- Show when data is loading. -->
<p ng-if="isLoading">
<em>Loading...</em>
</p>
 
<!-- Show when data has finished loading. -->
<ul ng-if="! isLoading">
<li ng-repeat="friend in friends">
 
{{ friend.name }}
 
</li>
</ul>
 
 
<!-- Initialize scripts. -->
<script type="text/javascript" src="../jquery/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="../angularjs/angular-1.2.4.min.js"></script>
<script type="text/javascript">
// Define the module for our AngularJS application.
var app = angular.module( "Demo", [] );
// -------------------------------------------------- //
// -------------------------------------------------- //
// I control the main demo.
app.controller(
"DemoController",
function( $scope, friendService ) {
// I determine if remote data is currently being loaded.
$scope.isLoading = false;
// I contain the data that we wan to render.
$scope.friends = [];
// I hold the handle on the current request for data. Since we want to
// be able to abort the request, mid-stream, we need to hold onto the
// request which will have the .abort() method on it.
var requestForFriends = null;
// ---
// PUBLIC METHODS.
// ---
// I abort the current request (if its running).
$scope.abortRequest = function() {
return( requestForFriends && requestForFriends.abort() );
};
// I load the remote data for the view.
$scope.loadData = function() {
// Flag the data is currently being loaded.
$scope.isLoading = true;
$scope.friends = [];
// Make a request for data. Note that we are saving a reference to
// this response rather than just piping it directly into a .then()
// call. This is because we need to be able to access the .abort()
// method on the request and we'll lose that original reference after
// we call the .then() method.
( requestForFriends = friendService.getFriends() ).then(
function( newFriends ) {
// Flag the data as loaded.
$scope.isLoading = false;
$scope.friends = newFriends;
},
function( errorMessage ) {
// Flag the data as loaded (or rather, done trying to load). loading).
$scope.isLoading = false;
console.warn( "Request for friends was rejected." );
console.info( "Error:", errorMessage );
}
);
};
}
);
// -------------------------------------------------- //
// -------------------------------------------------- //
// I am the friend repository.
app.service(
"friendService",
function( $http, $q ) {
// I get the list of friends from the remote server.
function getFriends() {
// The timeout property of the http request takes a deferred value
// that will abort the underying AJAX request if / when the deferred
// value is resolved.
var deferredAbort = $q.defer();
// Initiate the AJAX request.
var request = $http({
method: "get",
url: "./api/friends.cfm",
timeout: deferredAbort.promise
});
// Rather than returning the http-promise object, we want to pipe it
// through another promise so that we can "unwrap" the response
// without letting the http-transport mechansim leak out of the
// service layer.
var promise = request.then(
function( response ) {
return( response.data );
},
function( response ) {
return( $q.reject( "Something went wrong" ) );
}
);
// Now that we have the promise that we're going to return to the
// calling context, let's augment it with the abort method. Since
// the $http service uses a deferred value for the timeout, then
// all we have to do here is resolve the value and AngularJS will
// abort the underlying AJAX request.
promise.abort = function() {
deferredAbort.resolve();
};
// Since we're creating functions and passing them out of scope,
// we're creating object references that may be hard to garbage
// collect. As such, we can perform some clean-up once we know
// that the requests has finished.
promise.finally(
function() {
console.info( "Cleaning up object references." );
promise.abort = angular.noop;
deferredAbort = request = promise = null;
}
);
return( promise );
}
// Return the public API.
return({
getFriends: getFriends
});
}
);
</script>
 
</body>
</html>
mato75 commented

it does not work for me, also tried http://developer.rackspace.com/blog/cancelling-ajax-requests-in-angularjs-applications.html and the request is not aborted.

using $resource

    var c$resource = $resource,
          c$q = $q;
    function _createResourceInstance(aborter) {
        return c$resource(
            'url', { 'q': '@q' },
            {
                fetch: {
                    method: 'JSONP',
                    params: { 'q': '@q' },
                    timeout: aborter.promise
                }
            }
        );
    }

    function resourceReport2() {
        var aborter = c$q.defer();

        // Initiate the AJAX request.
        var resource = _createResourceInstance(aborter);

        return {
            getResource: function () {
                console.log(resource)
                return resource;
            },
            /**
             * Recreates the resource instance.
             */
            renew: function () {
                aborter = c$q.defer();
                resource = _createResourceInstance(aborter);
            },
            /**
             * Aborts current requests and recreate abortable resource.
             */
            abort: function () {
                aborter.resolve();
                this.renew();
            }
        };

    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.