Timeout cancelled with user action?


#1

Currently, I have a static timeout on all pages of my app, that redirects the user to the home page after 30 seconds.

The code is as simple as:

.controller('MyCtrl', ['$scope', '$state', '$timeout',
                      function($scope, $state, $timeout,) {

    ///...

    $timeout(function() {
      $state.go('Splash');
      }, 30000);

    }])

However, as soon as the User touches the screen, I’d like to reset the countdown to 30s. How would you do this?

Thanks.


#2

$timeout returns a promise which you can use to cancel a timeout

$timeout.cancel(promise)

And actually this is one of those features i’d actually implement on the $rootScope (oh… my… god… yes i said it… $rootScope… out come the pitchforks).

  • So i’d have a timer counting down on $rootScope
  • if it ever reaches zero i send out an event via $rootScope.$broadcast
  • controllers listen to the event with $scope.$on and do stuff.
  • i’d listen to a global event listener (window.onclick?) and if it ever gets triggered cancel the rootscope timer and restart.

#3

Thanks @jawache it seems to be a clever way to go!
I’ll try to do it soon and will tell you :smile:


#4

@jawache based on your idea, I started a Controller which seems to work as expected:

.controller('TestCtrl', ['$scope', '$rootScope', '$timeout', '$state',
                                function($scope, $rootScope, $timeout, $state) {

    $rootScope.new_timer = function() {
      console.log("function new_timer()");
      $rootScope.mytimer = $timeout(function() {
        $rootScope.$broadcast("timeover");
        console.log("timeover event sent");
        }, 5000);
    }

    $rootScope.cancel_timer = function() {
      console.log("function cancel_timer()");
      $timeout.cancel($rootScope.mytimer);
    }

    $rootScope.raz_timer = function() {
      console.log("function raz_timer()");
      $rootScope.cancel_timer();
      $rootScope.new_timer();
    }

}])

In each page of my app, I add this:

$rootScope.$on("timeover", function() {
      console.log("timeover event received -> redirection to Test")
      $state.go('Test');
    })

Now, the only missing thing is the global event listener.
However, I’m not sure how I’m supposed to add it in an ionic app.
Where do I have to put it sothat it is triggered in any page of my app?
And Why should I use windows.onclick instead of Ionic onGesture event?

Thanks for helping!


#5

The place to stick your code is in an app.run block.

Run Blocks
Run blocks are the closest thing in Angular to the main method. A run block is the code which needs to run to kickstart the application. It is executed after all of the services have been configured and the injector has been created. Run blocks typically contain code which is hard to unit-test, and for this reason should be declared in isolated modules, so that they can be ignored in the unit-tests.

You can inject services etc… into an app.run block. It’s run after angular has boostrapped itself and before any controllers have been instantiated so you’ll only need to have your code in one place.

As to which event to use? Not sure, haven’t had my morning coffee yet! I think you might have to experiment :slight_smile: