1

I have a problem accessing the functions properties from nested functions. I'm sure I've missed something, but after 3 hours of Google I just don't know what to look for. The background: I want to add a controller to angularjs, that reload the page after a certain time. My problem is the access from "this.reloadTicker()" to "this.enabled". The idea to rename the controller function and then access them doesn't work. One solution would be to store everything in "$scope", but is there a better solution?

My code:

ctrls.controller("reloaderCtrl", function reloader($scope) {
    this.enabled = true;
    this.paused = false;
    this.maxSecs = 30;
    this.secs = 30;
    this.reloadTicker = function() {
        if (reloader.enabled && !reloader.paused) {
            if (reloader.secs > 0) {
                reloader.secs--;
            } else {
                reloader.reload();
                reloader.secs = reloader.maxSecs;
            }
            $scope.$apply();
        }
        setTimeout(this, 1000);
    }
    this.reload = function() {
        $scope.$emit('doReload');
    }
    setTimeout(this.reloadTicker, 1000);
});
  • http://stackoverflow.com/questions/2130241/pass-correct-this-context-to-settimeout-callback – jandob Apr 05 '15 at 22:00
  • You can cache the `this` object: `var reloader = this;` and then in your nested function `reloader.enabled`. Or use the `Function.prototype.bind` function. – Ram Apr 05 '15 at 22:01

1 Answers1

0

You need to capture this in some variable:

ctrls.controller("reloaderCtrl", function ($scope) {
    var vm = this;
    vm.enabled = true;
    vm.paused = false;
    vm.maxSecs = 30;
    vm.secs = 30;

    vm.reloadTicker = function() {
        if (vm.enabled && !vm.paused) {
            if (vm.secs > 0) {
                vm.secs--;
            } else {
                vm.reload();
                vm.secs = vm.maxSecs;
            }
            $scope.$apply();
        }
        setTimeout(this, 1000);
    }
    vm.reload = function() {
        $scope.$emit('doReload');
    }
    setTimeout(vm.reloadTicker, 1000);
});

PS. I would recommend to use Angular $timeout instead of setTimeout ( https://docs.angularjs.org/api/ng/service/$timeout)

PSS. I would recommend to go through Angular Style Guide by John Papa. This is definetly good read (https://github.com/johnpapa/angular-styleguide)

Kaspars Ozols
  • 6,967
  • 1
  • 20
  • 33