Created
March 26, 2014 15:31
-
-
Save ScottGuymer/9786082 to your computer and use it in GitHub Desktop.
Angular $http interceptor to allow for a loading spinner whenever any ajax request is made. Could be extended to provide request logging and error handling.
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
<div id="loadingWidget" loading-widget> | |
<div class="loadingContent"> | |
<p> | |
Loading....Loading....Loading....Loading....Loading....Loading....Loading....Loading....Loading....Loading....Loading....Loading....Loading....Loading....Loading....Loading....Loading....Loading.... | |
</p> | |
</div> | |
</div> |
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
'use strict'; | |
// Declare module which depends on filters, and services | |
angular.module('notificationWidget', []) | |
// set up the interceptor | |
.config(['$httpProvider', function ($httpProvider) { | |
$httpProvider.interceptors.push(function ($q, $injector) { | |
var notificationChannel, | |
$http; | |
return { | |
// optional method | |
'request': function (config) { | |
// get requestNotificationChannel via $injector because of circular dependency problem | |
notificationChannel = notificationChannel || $injector.get('requestNotificationChannel'); | |
// send a notification requests are complete | |
notificationChannel.requestStarted(); | |
// do something on success | |
return config || $q.when(config); | |
}, | |
// optional method | |
'requestError': function (rejection) { | |
// get $http via $injector because of circular dependency problem | |
$http = $http || $injector.get('$http'); | |
// don't send notification until all requests are complete | |
if ($http.pendingRequests.length < 1) { | |
// get requestNotificationChannel via $injector because of circular dependency problem | |
notificationChannel = notificationChannel || $injector.get('requestNotificationChannel'); | |
// send a notification requests are complete | |
notificationChannel.requestEnded(); | |
} | |
return $q.reject(rejection); | |
}, | |
// optional method | |
'response': function (response) { | |
// get $http via $injector because of circular dependency problem | |
$http = $http || $injector.get('$http'); | |
// don't send notification until all requests are complete | |
if ($http.pendingRequests.length < 1) { | |
// get requestNotificationChannel via $injector because of circular dependency problem | |
notificationChannel = notificationChannel || $injector.get('requestNotificationChannel'); | |
// send a notification requests are complete | |
notificationChannel.requestEnded(); | |
} | |
// do something on success | |
return response || $q.when(response); | |
}, | |
// optional method | |
'responseError': function (rejection) { | |
// get $http via $injector because of circular dependency problem | |
$http = $http || $injector.get('$http'); | |
// don't send notification until all requests are complete | |
if ($http.pendingRequests.length < 1) { | |
// get requestNotificationChannel via $injector because of circular dependency problem | |
notificationChannel = notificationChannel || $injector.get('requestNotificationChannel'); | |
// send a notification requests are complete | |
notificationChannel.requestEnded(); | |
} | |
console.log('There was an AJAX error - DO SOMETHING MORE HERE') | |
return $q.reject(rejection); | |
} | |
} | |
}) | |
}]) | |
// declare the notification pub/sub channel | |
.factory('requestNotificationChannel', ['$rootScope', function ($rootScope) { | |
// private notification messages | |
var _START_REQUEST_ = '_START_REQUEST_'; | |
var _END_REQUEST_ = '_END_REQUEST_'; | |
// publish start request notification | |
var requestStarted = function () { | |
$rootScope.$broadcast(_START_REQUEST_); | |
}; | |
// publish end request notification | |
var requestEnded = function () { | |
$rootScope.$broadcast(_END_REQUEST_); | |
}; | |
// subscribe to start request notification | |
var onRequestStarted = function ($scope, handler) { | |
$scope.$on(_START_REQUEST_, function (event) { | |
handler(); | |
}); | |
}; | |
// subscribe to end request notification | |
var onRequestEnded = function ($scope, handler) { | |
$scope.$on(_END_REQUEST_, function (event) { | |
handler(); | |
}); | |
}; | |
return { | |
requestStarted: requestStarted, | |
requestEnded: requestEnded, | |
onRequestStarted: onRequestStarted, | |
onRequestEnded: onRequestEnded | |
}; | |
}]) | |
// declare the directive that will show and hide the loading widget | |
.directive('loadingWidget', ['requestNotificationChannel', function (requestNotificationChannel) { | |
return { | |
restrict: "A", | |
link: function (scope, element) { | |
// hide the element initially | |
element.hide(); | |
var startRequestHandler = function () { | |
// got the request start notification, show the element | |
element.show(); | |
}; | |
var endRequestHandler = function () { | |
// got the request start notification, show the element | |
element.hide(); | |
}; | |
// register for the request start notification | |
requestNotificationChannel.onRequestStarted(scope, startRequestHandler); | |
// register for the request end notification | |
requestNotificationChannel.onRequestEnded(scope, endRequestHandler); | |
} | |
}; | |
}]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment