Cordova plugins not working inside .config() in iOS

Calling cordova network plugin inside interceptor which is inside the config( function(){} ) is failing and it says - “undefined is not an object” for window.plugin.network.type

device - iPad

$httpProvider.interceptors.push(function($rootScope, $cordovaNetwork) {
return {
request: function(config) {
if ($cordovaNetwork.isOnline()) {
$rootScope.$broadcast(‘loading:show’);
return config;
}
},
response: function(response) {
$rootScope.$broadcast(‘loading:hide’);
return response;
},
responseError: function(rejection) {
$rootScope.$broadcast(‘loading:hide’);
return rejection;
}
}
})

http://ngcordova.com/docs/plugins/network/

The plugin can only be used after device ready

document.addEventListener("deviceready", function () {

And did you inject the plugin in de .config() ? I see you’ve injected it in the $httpProvider.

Yes . $httpProvider is inside config()

Initially .config() executes, then .run() executes.
$ionicPlatform.ready() is inside .run() …

The flow is like this…
.config() executes //plugin is used inside $httpProvider which is inside this
.run() executes //platform.ready is in here

since config executes before platform.ready(), the plugins are still undefined and gives an error.

The main requirement here is that on every http request, I need to intercept and check if the internet connection exist, if yes, proceed with the request. If not, block the request and show an ionic popup alert.

Please help me with this.

you can also put platform ready in config :slight_smile: … it’s not only for .run()

A better approach is how I do

  1. create a startercontroller (default controller)
  2. in the starter controller listen for device ready
  3. when ready … fire event
  4. create a .run() function to listen for the event

This way you always ensure the app is ready for device ready. So when .run() catches the event, you know device ready is … ready … and so are your plugins :slight_smile: … after that you can continue your normal flow and even check if you’re online or offline.

I don’t have a problem with .run()
I have a problem with .config()

I need to ensure that all plugins are loaded before the .config() executes…

yeah but … What I’m saying is … don’t use .config() for that.

I would advice you to rethink the flow.

Also … I had the same problem … so I created my own service to handle online/offline … so other controllers/services can use my service and not exposing the $cordovaNetwork …

maybe you can use it?

'use strict';
angular.module('myModule')

.service('NetworkService', ['$q', '$rootScope' , '$cordovaNetwork' ,  '$window' ,  function($q, $rootScope , $cordovaNetwork, $window  ) {
    
    var _isOnline   = true;
                
    var service = {
        isOnline    : isOnline,
        init    : init
    };
    return service;
        
    ////////////
    function _initLoaded() {
        $rootScope.$broadcast('network:afterInit' , { isOnline : _isOnline } );
    }
    
    function init() {
        
        $rootScope.$on('$cordovaNetwork:online', function(event, networkState) {
            _isOnline = true;                     
            $rootScope.$broadcast('network:online' , { networkState : networkState } );
        });

        // listen for Offline event
        $rootScope.$on('$cordovaNetwork:offline', function(event, networkState) {
            _isOnline = false;  
            var type = $cordovaNetwork.getNetwork();
       
            if(type !== 'none') {
                _isOnline   = true;
            }
            
            if(_isOnline === true) {
                $rootScope.$broadcast('network:online' , { networkState : networkState } );
            } else {
                $rootScope.$broadcast('network:offline' , { networkState : networkState } );
            }
        });          
        
        var isWebView = ionic.Platform.isWebView(); 
        if(isWebView === true) {
            
            // on device
            document.addEventListener('deviceready', function () {                
                _isOnline = $cordovaNetwork.isOnline();
                var type = $cordovaNetwork.getNetwork();
                if(!_isOnline) {
                    if(type !== 'none') {
                        _isOnline   = true;
                    }
                }
                _initLoaded();
            } , false);
            
        } else {
            // browser
            _isOnline = $window.navigator.onLine;   

            $window.addEventListener('online',  function(){
                $rootScope.$broadcast('network:online');
                _isOnline   = true;
            });
            
            $window.addEventListener('offline',  function(){
                $rootScope.$broadcast('network:offline');
                _isOnline   = false;
            });            
            
            _initLoaded();
        }          
    }
    
    function isOnline() {
        return _isOnline;
    }
    
    
}]);

Where have you placed the interceptor code?

Also in a .config()

But I don’t use a plugin like $cordova network in the http intercept

But I was thinking … why don’t you just skip the online check in your http intercept. so like

$httpProvider.interceptors.push(function($rootScope) {
            return {
                request: function(config) {

                        $rootScope.$broadcast('loading:show');
                        return config;
                    
                },
                response: function(response) {
                    $rootScope.$broadcast('loading:hide');
                    return response;
                },
                responseError: function(rejection) {
                    $rootScope.$broadcast('loading:hide');
                    return rejection;
                }
            }
        })

So it always try and make the intercept and show the loading and if something goes wrong (for instance no network) it always close the loading.

Thank you. Got it working :slight_smile:

1 Like