0

I am trying to make a basic function that adds 1 to the variable 'wood' every second.

In javascript, a simple

setInterval(function(){
    wood++;
}, 1000);

would do the trick.

In Angular, I've been shown

app.controller('RandomCtrl', function($interval){
    this.wood = 0;
    $interval(function(){
        this.wood++;
    }, 1000);
});

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
    var app = angular.module('app', []);
    app.controller('RandomCtrl', function($interval){
        this.wood = 0;
        $interval(function(){
            this.wood++;
            document.getElementById('p').innerHTML = this.wood;
        }, 1000);
    });  
</script>
<div ng-app='app' ng-controller='RandomCtrl as rand'>
    Wood: {{ rand.wood }}
    <br><br>Wood's value straight from the $interval:<p id='p'></p>
    So, the interval is fine, but the variable is undefined inside it, which is the whole point of me using this interval.
  <br><br>Also, I want this.wood to hold the value, nothing else.
</div>

However, the code above for some reason doesn't work.

It treats this.wood+1 as 'NaN' and this.wood as 'undefined'

Here's the snippet:

1
  • 3
    the this context is different in your angular example. use var self = this; in the outside function and use self.wood++ in the $interval. PS this is not angular specific it's javascript basics Commented Apr 4, 2015 at 22:11

2 Answers 2

2

From http://ryanmorr.com/understanding-scope-and-context-in-javascript/ :

Context is most often determined by how a function is invoked. When a function is called as a method of an object, this is set to the object the method is called on

When called as an unbound function, this will default to the global context or window object in the browser. However, if the function is executed in strict mode, the context will default to undefined.

Just use angulars $scope or a variable declared in the outer function scope:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
    var app = angular.module('app', []);
    app.controller('RandomCtrl', function($interval, $scope){
        var self = this;
        self.wood = 0;
        $scope.wood = 0;
        $interval(function(){
            $scope.wood++;
            self.wood++;
        }, 1000);
    });  
</script>
<div ng-app='app' ng-controller='RandomCtrl as rand'>
    Wood: {{ wood }} {{ rand.wood }}
    <br><br>Wood's value straight from the $interval:<p id='p'></p>
    So, the interval is fine, but the variable is undefined inside it, which is the whole point of me using this interval.
  <br><br>Also, I want this.wood to hold the value, nothing else.
</div>

Sign up to request clarification or add additional context in comments.

Comments

0

The problem here is that you are trying to access your scope in a new context, where 'this' no longer refers to your angular controller.

In addition, Angular allows variables to be accessible through your controller's scope. If you want to use your variable wood in your template, you have to assign it on the scope object.

Your code should read:

app.controller('RandomCtrl', function($interval, $scope){
$scope.wood = 0;
$interval(function(){
    $scope.wood++;
}, 1000);
});

The reason why this fails silently is that this.TEST++ returns NaN and not an error.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.