6

Is there a way to call a JavaScript function if a javascript variable changes values using jQuery?

Something to the extend of -

var test = 1;
test = 2; // calls a javascript function
test = 3; // calls a javascript function

This way I wouldn't have to add an onchange event to so many different functions.

8 Answers 8

22

(Something seems a bit carelessly planned in your code if you need functionality like that)

The easiest way to add that feature is to create a function for updating your variable, that also calls whatever other function you want to.

Instead of:

var test = 1;
test = 2; // calls a javascript function
test = 3; // calls a javascript function

You do:

var test = 1;

function set_test(newval) {
  test = newval;
  my_callback(); // this is whatever you wanted to call onChange
}

set_test(2);
set_test(3);
Sign up to request clarification or add additional context in comments.

2 Comments

+1 After reading the others, this is clearly the best answer.
+1 for "Something seems a bit carelessly planned in your code if you need functionality like that". Quite true.
6

try this, it's real variable change event:

var book = {
    _year: 2004,
    edition: 1
};
Object.defineProperty(book, "year", {
    get: function(){
        return this._year;
    },
    set: function(newValue){
        this._year=newValue;
        this.edition=newValue-2004;
        alert(this._year);
        alert(this.edition);
    }
});

book.year=2017
// will alert 2017 and 13

Comments

2

No, there is not, just polling with setInterval or setTimeout or callbacks. Events only apply to DOM. I'd suggest that you try to go with callbacks and do things like this:

function foo(data, callback)
{
    // do things with data
    callback(data);
}

function bar(data)
{
    console.log('callback can has', data);
}

foo('baz', bar);

It's a rough example, but should give you the idea.

Comments

1

One option is to wrap your data into a heavier object.

var Watching = function(){
    var a;

    this.getA(){
        return a;
    };

    this.setA(value){
        a = value;
        this.trigger('watch');
    };

    his.watchA(callback){
        this.bind('watch', callback);
    };
};

var obj = new Watching();
obj.watchA(function(){ alert('changed'); });
obj.setA(2);

Comments

1

This doesn't answer your question exactly, but it may solve your problem: make your variable as html content of an element, then use jQuery change() event

<script>
document.write("<div id='test'>"+test+"</div>";
$("#test").change(function(){//your script here});
</script>

Comments

1

You can create a class to be notified when your variable changed. this is the class:

class ListeningVariable {
    constructor(val, changeHandler) {
        this.val = val;
        this.changeHandler = changeHandler
    }
    set value(val) {
        if (this.val !== val) {
            this.changeHandler(val);
        }
        this.val = val;
    }
    changeHandler(val) {}
}

Then you can create an instance of this class instead of your variable:

let myVar = new ListeningVariable(25/*initialize*/, function(val) {
    console.log("variable Changed to:", val);
}/*handler function*/);

And when you want to change your variable, just use this code:

myVar.value = 20; // calls the changeHandler function
myVar.value = 20; // does't call the changeHandler function
myVar.value = 40; // calls the changeHandler function

Comments

0

You can do something like this with setting intervals to keep track of change:

var dataToChange = 1;
var key = dataToChange;
var int = setInterval(() => {
    if (dataToChange != key) {
        console.log('changed'); /// if data changes
        clearInterval(int);
    } else {
        console.log('nothing changed'); /// while nothing changes
    }
}, 3000);
setTimeout(() => {
    ///// supposedly this is when the variable changes
    dataToChange = 2;
}, 9000);

Comments

-1
The below function will poll for changes in the test variable every 5 seconds:

// initialize test variable globally
var test = 1;

// global variable to store the previous value of test
// which is updated every 5 seconds
var tmp = test;

setInterval("pollForVariableChange()", 5000);

function pollForVariableChange() {
    if (tmp != test) {
        alert('Value of test has changed to ' + test);
    }
    tmp = test;
}

Comments

Your Answer

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