Skip to content

Instantly share code, notes, and snippets.

@KariHe
Last active December 15, 2016 13:48
Show Gist options
  • Save KariHe/2c0a49efdaf9a3ea29f2 to your computer and use it in GitHub Desktop.
Save KariHe/2c0a49efdaf9a3ea29f2 to your computer and use it in GitHub Desktop.
Using AngularJS resource object for loader
angular.module('myApp').factory('httpLoaderInterceptor', ['$rootScope', function($rootScope) {
// Active request count
var requestCount = 0;
function startRequest(config) {
// If no request ongoing, then broadcast start event
if( !requestCount ) {
$rootScope.$broadcast('httpLoaderStart');
}
requestCount++;
return config;
}
function endRequest(arg) {
// No request ongoing, so make sure we don’t go to negative count
if( !requestCount )
return;
requestCount--;
// If it was last ongoing request, broadcast event
if( !requestCount ) {
$rootScope.$broadcast('httpLoaderEnd');
}
return arg;
}
// Return interceptor configuration object
return {
'request': startRequest,
'requestError': endRequest,
'response': endRequest,
'responseError': endRequest
};
}]);
angular.module('myApp').config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('httpLoaderInterceptor');
}]);
angular.module('myApp').directive('httpLoader', function() {
return {
restrict: 'EA',
link: function(scope, element) {
// Store original display mode of element
var shownType = element.css('display');
function hideElement() {
element.css('display', 'none');
}
scope.$on('httpLoaderStart', function() {
element.css('display', shownType);
});
scope.$on('httpLoaderEnd',hideElement);
// Initially hidden
hideElement();
}
};
});
<body class=“ng-cloak”>
...
<div class=“ng-cloak” ng-view></div>
...
</body>
<body>
<div class="full-page-overlay" route-loader>
<i class="icon-loader spin">Loading…</i>
</div>
<div ng-view></div>
angular.module('myApp').factory('Article', function( $resource ) {
return $resource('/api/article/:id');
});
angular.module('myApp').controller('ArticleCtrl', function($scope, $routeParams, Article) {
$scope.article = Article.get( { id: $routeParams.id } );
});
<div ng-hide=“article.$resolved”>
<i class=“icon-loader spin”>Loading…</i>
<div>
<div ng-show=“article.$resolved”>
<h1>{{ article.title }}</h1>
<p>{{ artcile.content }}</p>
</div>
angular.module('myApp').directive('routeLoader', function() {
return {
restrict: 'EA',
link: function(scope, element) {
// Store original display mode of element
var shownType = element.css('display');
function hideElement() {
element.css('display', 'none');
}
scope.$on('$routeChangeStart', function() {
element.css('display', shownType);
});
scope.$on('$routeChangeSuccess',hideElement);
scope.$on('$routeChangeError', hideElement);
// Initially element is hidden
hideElement();
}
}
});
angular.module('myApp').config( function($routeProvider) {
$routeProvider.
when("/article/:id", {
templateUrl: 'templates/article.html',
controller: 'ArticleCtrl',
resolve: {
article: ['Article', '$route', function(Article, $route) {
return Article.get({id: $route.current.params.id}).$promise;
}]
}
});
….
});
angular.module('myApp').controller('ArticleCtrl', function($scope, article) {
$scope.article = article;
});
@everdimension
Copy link

In your interceptor factory, don't you need to reject the arguments for the requestError and responeError functions? Otherwise the appropriate error handlers will not be called.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment