Search code examples
javascriptknockout.jsknockout-2.0

Only change observable if it's not already set to some value in knockout.js


I have an observable in knockout.js:

var test = ko.observable();

test({view: 'abc',model : 'newmodel'});

I want to check if the variable test already contains:

{view: 'abc',model : 'newmodel'}

If it doesn't, I want to add the entry. How do I check this when using knockout.js?

The tough part is getting to know the object details.


Solution

  • You can retrieve the current value of an observable using (). I.e.:

    var currentValue = test();
    

    To check if this references the same object, you can use the === operator:

    var newValue = { view: 'abc', model: 'newmodel' };
    var isTheSame = currentValue === newValue;
    

    Note that when you set an observable's value, knockout already checks if the new value actually differs from the old one. If they're the same, knockout will not notify any subscribers (unless you explicitly tell it to).

    If you want to compare if the objects contain equal keys and values, you need some sort of "deep compare" method. (How to determine equality for two JavaScript objects?)

    I'm not sure what you mean by "add the entry". To set the new object, use:

    test(newValue);
    

    If you want to add the properties in the newValue variable to test's value, you can use Object.assign (make sure to check if your browser supports it)

    var combinedValue = Object.assign(currentValue, newValue);
    test(combinedValue);
    

    Object.assign maps all of its parameters' keys and values to the first parameter object. It overwrites any duplicate keys with the latest parameter's value.

    E.g.:

    var test = ko.observable({ a: 1, b: 1 });
    var newValue = { b: 2, c: 3 };
    test(Object.assign(test(), newValue));
    
    console.log(test()); // Will print: { a: 1, b: 2, c: 3 }