2

Having the following model:

  var dataModel = ko.observable({ someProp: ko.observable() });

  var isValid = ko.pureComputed(function () {
    return dataModel().isValid;
  });

I have the following function:

      function testMe() {
          dataModel().isValid = false; // This does not work, why?
          console.log("isValid: " + isValid()); // Doesn't update, shows old value 

          dataModel({ isValid: false }); // This works however I loose all other properties
          console.log("isValid: " + isValid()); // Prints correctly updated value

          console.log(ko.toJSON(dataModel()));          
      }

Whenever I run testMe()

dataModel.isValid = false

and execute

console.log("isValid: " + isValid())

it's still set to "true" even I've set it to false above...why?. The only way I got it to work is to do

dataModel({ isValid: false }); however this way I loose all other properties in my model. How can I make this work?

What am i doing wrong?

ShaneKm
  • 20,823
  • 43
  • 167
  • 296
  • 1
    If I run your code with I do not see "true" in any instance, see [this jsfiddle](https://jsfiddle.net/8fdyyhr2/), could you please try to create an "[mcve]" and explain *why* you expect said results? – Jeroen Sep 08 '16 at 20:18
  • Also, realize that if a (pure)computed depends on a variable that is *not* observable, it might not get updated correctly. – Jeroen Sep 08 '16 at 20:25

1 Answers1

7

isValid is not an observable. A computed will only know to update if one of its observables has changed. Alternatively, you can tell Knockout that dataModel has changed (which, being an observable that the computed looks at, will cause the computed to recompute) using dataModel.valueHasMutated().

I would recommend using an observable, though. Try something like this:

var dataModel = ko.observable({
  someProp: ko.observable(),
  isValid: ko.observable(true)
});

var isValid = ko.pureComputed(function() {
  return dataModel().isValid();
});

function testMe() {
  console.log("isValid: " + isValid());
  dataModel().isValid(false);
  console.log("isValid: " + isValid());

  console.log(ko.toJSON(dataModel()));
}

testMe();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
Community
  • 1
  • 1
Roy J
  • 42,522
  • 10
  • 78
  • 102
  • right on the money. thanks so much!. Also, a question. why does @Jeroen's example works even though isValid is not an observable? https://jsfiddle.net/8fdyyhr2/ – ShaneKm Sep 08 '16 at 20:33
  • 1
    @ShaneKm In his example, the value of `isValid` never changes. It starts false and stays false. That was what his comment was saying. – Roy J Sep 08 '16 at 21:13