TemplateURL for ionicLoading when used with global interceptors

Hello can anyone suggest me how to use $ionicLoading when used with global HTTP interceptors?

myApp.config(['$httpProvider', '$stateProvider', '$urlRouterProvider', 
                function($httpProvider, $stateProvider, $urlRouterProvider) {
    
    $httpProvider.interceptors.push(function($rootScope) {
        return {
            request: function(config) {
                $rootScope.$broadcast('loading:show')
                return config
            },
            response: function(response) {
                $rootScope.$broadcast('loading:hide')
                return response
            }
        }
    });

myApp.run(function($rootScope, $ionicLoading) {
      $rootScope.$on('loading:show', function() {
        $ionicLoading.show({templateUrl: 'loading.html'})
      })
});

Service

myApp.service('SomeService', ['$http', '$ionicLoading', '$q', function($http, $ionicLoading, $q){

    return{
        getAll : function(){
            var deferred = $q.defer();
            $http.get('https://api.myjson.com/bins/').then
                (
                    function(resp){
                        deferred.resolve(resp.data);
                    }, 
                    function(err){
                        $ionicLoading.hide();
                        console.log(err.status);
                    }
                );
            return deferred.promise; 
        }
    }
}]);

I did inject $ionicLoading into the controller also. Yet still I see no loading screen.
I even tried every combination of 'templateUrl', template but still no success.

does not work.

I even made constant of Ionicloading. Still no result.

Its a simple Typo, try using templateUrl then it should work!

Nope! does not work. Actually URL is a typo here in the forum and not in my original code base.

Look at the detailed question.

okey does the loader show?

if not, the problem cloud be that the run method was not executed when the broadcast was fired.
but i don’t have experience with $httpProvider

No the loader does not show. I am stuck with the same screen but UI interactions are blocked.
Whats wrong with this? :frowning:

1 Like

are the interceptors called? cloud you add console.log so you can see if its get executed?

I have got it to working somehow. Now I am stuck with a new problem.

The global $ionicLoading just appears for a second and then disappears even though the promise is not yet resolved and network still shows the request as pending.

can you try it with this:

  $http({method: 'GET', url: '/someUrl'}).
    success(function(data, status, headers, config) {
         deferred.resolve(data);
    }).
    error(function(data, status, headers, config) {
         $ionicLoading.hide();
         console.log(data);
    });

Now I know the problem.

response: function(response) { 
  $rootScope.$broadcast('loading:hide')
  return response
}

The $http Interceptor is firing the response function even before the response has been resolved. The response of data (the remote json file) is still pending but yet the response function is fired. I dont understand. How is that possible. What parameters returned by the server is the actual response?

I did figure out now. The response function is not called on actually obtaining the complete remote JSON file but on obtaining some HTTP headers. Like this:

Object {data: Array[2], status: 200, headers: function, config: Object, statusText: "OK"}

This is instantaneous. So after that valid data exist on the remote server, the fetching begins. But response function makes $ionicLoading hide away when the client is still waiting for the complete file.

see my post below. What do you think?

hmm strange.
I just found this:

app.config(['$httpProvider', function ($httpProvider) {
    var $http,
        interceptor = ['$q', '$injector', function ($q, $injector) {
            var error;

            function success(response) {
                // get $http via $injector because of circular dependency problem
                $http = $http || $injector.get('$http');
                if($http.pendingRequests.length < 1) {
                    $('#loadingWidget').hide();
                }
                return response;
            }

            function error(response) {
                // get $http via $injector because of circular dependency problem
                $http = $http || $injector.get('$http');
                if($http.pendingRequests.length < 1) {
                    $('#loadingWidget').hide();
                }
                return $q.reject(response);
            }

            return function (promise) {
                $('#loadingWidget').show();
                return promise.then(success, error);
            }
        }];

    $httpProvider.responseInterceptors.push(interceptor);
}]);

the trick in this example should be this: if($http.pendingRequests.length < 1) i hope this helps.

Did you try it? Does it work for you? Try that and let me know.

nope because i dont use $http atm, just trying to help here :smiley:

Yeah! It works. I made a few changes to it. Boy gotta spend more time learning the features offered by Angular.

1 Like

same goes to me its still a big ? sometimes :smiley:

Yeah I did not know $http.pending request till today. Back to docs now.