$ionicLoading in http interceptor

Every time I make an http request, I want to show a ionicLoading dialog and then hide it when the request completes. I think the DRYest way to do this is as an interceptor (so I don’t have to repeat the show() and hide() function calls around every $http.get

Here is my code:

.config(function($stateProvider, $urlRouterProvider, $httpProvider) {

  $httpProvider.interceptors.push(function($q, $rootScope, $injector, $ionicLoading) {
    return {
      request: function(request) {
        $ionicLoading.show({content: "Loading...", showBackdrop: true, maxWidth: 200, showDelay: 100});
        return request || $q.when(request);
      },
      response: function(response) {
        $ionicLoading.hide();
        return response || $q.when(response);
      }
    };

    // controller code, etc..
  });

But I get an error: Error: [$injector:cdep] Circular dependency found: $compile <- $ionicTemplateLoader <- $ionicLoading <- $http <- $templateFactory <- $view <- $state

What’s the issue here? Is having the ionicLoading dependency in the interceptor not the right approach?

1 Like

You can get around this by injecting it manually at runtime.

 $injector.get("$ionicLoading").show();

I create a service so I can have some defaults like this:

.factory('BusyService', ['$ionicLoading', function($ionicLoading) {
  return {
    show: function(content) {
      $ionicLoading.show({
        content: content || 'Loading Data',
        animation: 'fade-in',
        showBackdrop: true,
        showDelay: 300
      });
    },

    hide: function() {
      $ionicLoading.hide();	
    }
  };
}])

Then you can inject this service manually in your http interceptor.

2 Likes

Cool thanks, works great!

I have same issue with service you have write with $ionicPopup. Bu I also having same injection error. What is the right way to using $ionicLoading or $ionicPopup with service or not.

You can use a service or inject it directly. I wanted to use a service so that I could default some common values without having to define them every time.

@james_dn Actually I was also doing the same thing and got this error. As you said in the post we dont have to call .show and .hide everytime when we make ajax request. But in the solution provided my @keithdmoore the circular dependency issue is solved but again we have to call $injector.get("$ionicLoading").show(); and $injector.get("$ionicLoading").hide(); before and after the http request.

Also, $injector.get("$ionicLoading").show() can be called from controller ? I am calling from controller before I request for the http service.

You can also do this now in your app.js

.constant('$ionicLoadingConfig', {
  template: '<h3><icon ios="ion-ios7-reloading" android="ion-loading-c" default="ion-refreshing"></icon></h3>Loading...'
})

And create an HttpInterceptor similiar to this:

https://github.com/trendicity/trendicity/blob/master/app/scripts/services/interceptors.js

And then put this in your app.js:

.config(function($httpProvider) {
  $httpProvider.interceptors.push('TrendicityInterceptor');
});

Then you don’t have to worry about calling the show() and hide for every HTTP request. $injector is widely used to resolve circular dependency issues by the way.

There is post by Ionic team - http://learn.ionicframework.com/formulas/loading-screen-with-interceptors/

1 Like

There is a bower component that does this: