niczak
niczak

Reputation: 3917

Access global variables in setInterval()

I have a function to generate some random-ish numbers and inside that function I make a call to setInterval() because I need those numbers to refresh every 2 seconds.

function genSine(val1, val2) {

    var freq = 0.1; // angular frequency

    var coords = function(x, y) {
        var amplitude = Math.floor((Math.random()*10)+1);
        var phase = Math.floor((Math.random()*20)+1);
        return {
            x : Math.sin(freq * (val1 + phase) * amplitude) + Math.floor((Math.random()*100)+1),
            y : Math.sin(freq * (val2 + phase) * amplitude) + Math.floor((Math.random()*100)+1)
        };
    }

    setInterval(function() {
        current = coords(50, 50);
        console.log('Val 1: ' + current.x);
        console.log('Val 2: ' + current.y);
    }, 2000);
}

genSine(10, 20);

This is all well and good, the values update as expected but my goal is to have two global variables (let's call them val1/val2) update within that setInterval() function. It appears I have a scoping issue because those variables are not accessible within the function and I can not access the 'current' variable from outside that function. I know I am missing something here, what is it?

Fiddle: http://jsfiddle.net/niczak/4uNen/1/

Upvotes: 3

Views: 16779

Answers (3)

Renish Gotecha
Renish Gotecha

Reputation: 2522

in typescript i did following code. in the below code i assign _this with the value of this

export class HomeComponent implements OnInit {
  lat: number = 22.008515;
  setMarker(){
   console.log('Inside setMarker Lat : '+this.lat); // 22.008515
    var _this = this;
    setInterval(function() {
     console.log('Inside setInterval this.lat : '+this.lat); // undefined
     console.log('Inside setInterval _this.lat : '+_this.lat); // 22.008515
    }, 8000)
  }
}

Upvotes: 0

user1618143
user1618143

Reputation: 1748

You just need to define var current = {}; in the global scope, and be sure not to define var current in any other scope. current=[whatever]; is fine, as long as there's no var.

Edit: I'm not sure what you did, but I fixed your fiddle with this code:

var current;
function genSine(val1, val2) {

    var freq = 0.1; // angular frequency

   var coords = function(x, y) {
        var amplitude = Math.floor((Math.random()*10)+10);
        var phase = Math.floor((Math.random()*20)+10);
        return {
            x : Math.sin(freq * (val1 + phase) * amplitude) + Math.floor((Math.random()*100)+1),
            y : Math.sin(freq * (val2 + phase) * amplitude) + Math.floor((Math.random()*100)+1)
        };
    }

    setInterval(function() {
        current = coords(50, 50);
        console.log(current);
        $(".display").html(JSON.stringify(current));
    }, 500);
}

genSine(10, 20);

setInterval(function() {
    $(".display2").html("d2:"+JSON.stringify(current));
}, 200);

Upvotes: 3

putvande
putvande

Reputation: 15213

Your current is fine in that scope, it is your coords function that is not in the right scope. Put that in the global scope together with the freq variable:

var freq = 0.1; // angular frequency
var coords = function (x, y) {
    var amplitude = Math.floor((Math.random() * 10) + 1);
    var phase = Math.floor((Math.random() * 20) + 1);
    return {
        x: Math.sin(freq * (val1 + phase) * amplitude) + Math.floor((Math.random() * 100) + 1),
        y: Math.sin(freq * (val2 + phase) * amplitude) + Math.floor((Math.random() * 100) + 1)
    };
}

function genSine(val1, val2) {

    setInterval(function () {
        current = coords(50, 50);
        console.log('Val 1: ' + current.x);
        console.log('Val 2: ' + current.y);
    }, 2000);
}

genSine(10, 20);

Upvotes: 0

Related Questions