How to Handle Network Error with Pull To Refresh?

Hi,

I think title says it all.

Details:

My app needs network connection to pull data from back end. I am trying to test different scenarios to handle network or communication error.

In my controller where I fetch the data, I have set the timeout option

$http.get('fetch data ', {timeout: 15000})
    .then(function(response) {
         //set some data
    },
    function(error) {
        alert('Error Message");
    }
});

I have tested this with network turned off on my device and it works.

Inside the same controller, I have a “doRefresh()” function for “ion-refresher” which basically does the same thing but its not working.

Cases

  1. Network is initially ON: When app is opened, it fetches the data normally and pull to refresh also works fine.

  2. Network is initially OFF: When app is loaded, controllers timeout works and shows the message after timeout.

  3. Network is still OFF: If I do a pull to refresh at this time, I am expecting the same behavior to show the message after timeout but it doesn’t. The icon keeps on spinning without any hint.

  4. After the case 2, I manually turn on the network and did pull to refresh. In this case I was expecting the behavior of case 1 but icon still keeps spinning without any data refresh and error message.

Am I missing something? Can somebody provide me the clue on how to handle this?

Thanks!

You can simply do if ($cordovaNetwork.isOffline()) to display appropriate message

Thanks for the quick reply. I have looked to this solution. This is one of the possible solution but may not be reason for communication error.

There are many possibilities like:

  1. Device is connected to wifi router which doesn’t have real internet connection
  2. Unreliable connection to communicate on time
  3. Server too busy to respond

etc.

That’s why I tried to use the timeout solution. Basically on my pull to refresh implementation, it just tries to grab data from server. If success, it sets some scopes. If timeout (failied) then shows error message. But for some reason this is not happening in my test scenarios.

Basically what I am trying to achieve is to recover from network error situation without relaunching the App.

Example:

  1. User forgot to enable network and launches the app.
  2. Error occurs and user gets the message.
  3. Then he/she turns on the network and continues with app without closing the App and relaunching again.

This is bit of a high level approach I think without worrying about which hardware is on or off. All we care about is the reliable communication.

Any clue?

Thanks!

Interesting, you can pass timeout as a promise to Angular $http. and use it like so: http://stackoverflow.com/questions/21915834/angular-http-setting-a-promise-on-the-timeout-config

I didn’t know about it

Thanks, will try that out… actually my code is something similar to that.

The thing I am trying to figure out is why pull to refresh code doesn’t execute (or it appears so) after error (by error I mean network is turned off first and back again after first error message).

For the test purpose, I am just testing this code.

on my html

<ion-refresher on-refresh="doRefresh()">

on my controller

$scope.doRefresh = function() {
    $ionicLoading.show({
        template: 'Loading...'
    });
}
  1. If app is launched with network ON this shows up fine and it does refresh
  2. If app is launched with network OFF, then I get the alert that network is off (as expected). But after network is turned ON while app is still running and try to do the pull to refresh, it doesn’t execute.

Before going any further, I need to figure out what happens in this situation. Specially why the code is not executing.

My expectation was pull to refresh should execute and try to refresh data as name suggests. But its not happening.

Need some clues & suggestion.

Thanks!

Actually I found the solution after some tweaking. It was not obvious at first.

My topic should have been “How to Recover From Network Error in Ionic?” but at first saw the problem in Pull to Refresh.

Anyway here is the code I first used in my controller. Controller have $http.get (outer get) and inside it is pull to refresh code which basically does same thing when user manually pull to refresh it.

$http.get('fetch data from API', {timeout: 15000})
.then(function(response) { //success
     //do something
    //broadcast that refresh is complete
    $scope.$broadcast('scroll.refreshComplete');


	//pull to refresh
	$scope.doRefresh = function() {
	    //get data and process
	    $http.get('fetch data from API', {timeout: 15000})
	    .then(function(response) {
	        //do something
	        //broadcast that refresh is complete
	        $scope.$broadcast('scroll.refreshComplete');
	    },
	    function(error){
	        $ionicPopup.alert({
	            title: "Connection Error",
	            content: "This App requires network connection. Check if network is turned on and connection is okay. Try pulling to refresh again."
	        });
	        $scope.$broadcast('scroll.refreshComplete');
	    });
	}


},
function(error) { //error
    $ionicPopup.alert({
        title: "Connection Error",
        content: "This App requires network connection. Check if network is turned on and connection is okay. Try pulling to refresh again."
    });
    $scope.$broadcast('scroll.refreshComplete');
}
});

The reason I was seeing the behavior of Pull to refresh not executing is that I have implemented on the “.then” (or success) part. Actually it was working fine. What happened is when app is loaded with network connection OFF, it executed the outer error (controller’s error) function, which doesn’t have pull to refresh code. So expecting Pull to Refresh come to rescue after error was not working.

In my second code I duplicated the Pull to refresh code on controller’s error function also and it worked perfectly as expected. Though duplicate codes, seems it have to be done this way.

$http.get('fetch data from API', {timeout: 15000})
.then(function(response) { //success
     //do something
    //broadcast that refresh is complete
    $scope.$broadcast('scroll.refreshComplete');


	//pull to refresh
	$scope.doRefresh = function() {
	    //get data and process
	    $http.get('fetch data from API', {timeout: 15000})
	    .then(function(response) {
	        //do something
	        //broadcast that refresh is complete
	        $scope.$broadcast('scroll.refreshComplete');
	    },
	    function(error){
	        $ionicPopup.alert({
	            title: "Connection Error",
	            content: "This App requires network connection. Check if network is turned on and connection is okay. Try pulling to refresh again."
	        });
	        $scope.$broadcast('scroll.refreshComplete');
	    });
	}


},
function(error) { //error
    $ionicPopup.alert({
        title: "Connection Error",
        content: "This App requires network connection. Check if network is turned on and connection is okay. Try pulling to refresh again."
    });
    $scope.$broadcast('scroll.refreshComplete');

	//pull to refresh
	$scope.doRefresh = function() {
	    //get data and process
	    $http.get('fetch data from API', {timeout: 15000})
	    .then(function(response) {
	        //do something
	        //broadcast that refresh is complete
	        $scope.$broadcast('scroll.refreshComplete');
	    },
	    function(error){
	        $ionicPopup.alert({
	            title: "Connection Error",
	            content: "This App requires network connection. Check if network is turned on and connection is okay. Try pulling to refresh again."
	        });
	        $scope.$broadcast('scroll.refreshComplete');
	    });
	}
    
}
});

Since both $http.get (controller’s get and pull to refresh get) function have timeout set. It is even responsive when network error occurs on the middle of something.

Case 1

  1. Network turned OFF
  2. Opening app shows the error message.
  3. Turn on (or fix the network) then Pull to refresh to continue.

Case 2.

  1. Initially Network is fine and app is loading and working fine
  2. Network error occurs in the middle of operation. Either controller’s function of doRefresh function notices (if user was doing pull to refresh at that time) and show error message.
  3. After user fixes the network, all user have to do is pull to refresh the data.

By the way there is another approach to that also.

  1. When network error is detected, user get error message and button to refresh the page.
  2. When clicked, it will reload the entire page using $window.location.reload(true); so if network is okay, it should load and fetch data normally.

For me personally, former solution is sleek.

I went on to explain a bit hoping it will help newbie like me wanted to implement similar feature.

Thanks anyway for the help.

1 Like