Created
May 3, 2014 01:27
Aborting An AJAX Request In AngularJS Using httpi
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html ng-app="Demo"> | |
<head> | |
<meta charset="utf-8" /> | |
<title> | |
Aborting AJAX Requests In AngularJS Using httpi | |
</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 In AngularJS Using httpi | |
</h1> | |
<!-- List of friends. --> | |
<ul> | |
<li ng-repeat="friend in friends"> | |
<a ng-click="showFriend( friend )">{{ friend.name }}</a> | |
</li> | |
</ul> | |
<!-- Friend detail. --> | |
<div ng-if="friend"> | |
<hr /> | |
<p> | |
<strong>ID</strong>: {{ friend.id }} <br /> | |
<strong>Name</strong>: {{ friend.name }} <br /> | |
<strong>Job</strong>: {{ friend.job }} <br /> | |
<strong>Bio (Bacon Ipsum)</strong>: {{ friend.bio }} <br /> | |
</p> | |
</div> | |
<!-- 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" src="./httpi.js"></script> | |
<script type="text/javascript"> | |
// Define the module for our AngularJS application. | |
var app = angular.module( "Demo", [ "httpi" ] ); | |
// -------------------------------------------------- // | |
// -------------------------------------------------- // | |
// I control the main demo. | |
app.controller( | |
"DemoController", | |
function( $scope, friendService ) { | |
// I contain the data that we are going to render. | |
$scope.friends = []; | |
$scope.friend = null; | |
// I hold on the most recent request for data for this interface. We need | |
// to hold on to this so that we can abort it (when necessary). | |
var pendingRequest = null; | |
// Initialize the list. | |
loadFriends(); | |
// --- | |
// PUBLIC METHODS. | |
// --- | |
// I get the given friend from the repository. | |
$scope.showFriend = function( friend ) { | |
// If we have a pending request, it's important to abort it. If we | |
// don't, then the asynchronous nature of our data access requests | |
// could leave our view-model in an unexpected state (if the | |
// requests are resolved in an order that is different from that in | |
// which they were initiated). | |
if ( pendingRequest ) { | |
pendingRequest.abort(); | |
} | |
// Store the primary promise (before invoking .then) since this is | |
// the object that has the .abort() method (courtesy of httpi). Once | |
// you call .then(), you lose access to .abort(). | |
pendingRequest = friendService.getFriend( friend.id ); | |
// Handle data response. | |
pendingRequest.then( | |
function( newFriend ) { | |
$scope.friend = newFriend; | |
}, | |
function( code ) { | |
console.warn( "Friend couldn't be loaded." ); | |
} | |
); | |
}; | |
// --- | |
// PRIVATE METHODS. | |
// --- | |
// I get the list of friends from the repository. | |
function loadFriends() { | |
friendService.getFriends().then( | |
function( newFriends ) { | |
$scope.friends = newFriends; | |
} | |
); | |
} | |
} | |
); | |
// -------------------------------------------------- // | |
// -------------------------------------------------- // | |
// I provide access to the the friend repository. | |
app.service( | |
"friendService", | |
function( httpi, $q ) { | |
// Return the public API. | |
return({ | |
getFriend: getFriend, | |
getFriends: getFriends | |
}); | |
// --- | |
// PUBLIC METHODS. | |
// --- | |
// I get the friend with the given ID. | |
function getFriend( id ) { | |
var request = httpi({ | |
method: "get", | |
url: "./api/friend.cfm", | |
params: { | |
id: id | |
} | |
}); | |
return( prepareResponse( request ) ); | |
} | |
// I get the list of friends from the remote server. | |
function getFriends() { | |
var request = httpi({ | |
method: "get", | |
url: "./api/friends.cfm" | |
}); | |
return( prepareResponse( request ) ); | |
} | |
// --- | |
// PRIVATE METHODS. | |
// --- | |
// Prepare the raw httpi response for use in the calling context. The | |
// goal here is two-fold: to encapsulate the underlying AJAX | |
// transportation mechanism; but, more importantly, to wire the "abort" | |
// method, provided by httpi service into the promise that we return to | |
// the calling context. | |
function prepareResponse( request ) { | |
// "Unwrap" the AJAX response. | |
var promise = request.then( | |
function handleResolve( response ) { | |
return( response.data ); | |
}, | |
function handleReject( response ) { | |
return( $q.reject( response.status ) ); | |
} | |
); | |
// Wire in the underlying abort method. | |
promise.abort = request.abort; | |
// No matter what happens with the request, free up the object | |
// references in order to help the garbage collection. | |
promise.finally( | |
function handleFinally() { | |
request = promise = null; | |
} | |
); | |
return( promise ); | |
} | |
} | |
); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment