Skip to content
Advertisement

Knockout JS – make observable dynamically modified object

Is possible to make dynamically changed JS object as a Knockout JS observable?

I mean I have this.statuses = ko.observable({}) and when I call API and get response, I’ll put the message here under some “identifiers”. Later I need to get any “last” status if necessary:

  set_status(owner, status, api_response) {
    if (!(owner in this.statuses)) this.statuses[owner] = {};
    this.statuses[owner][status] = api_response;
  }

  get_status(owner, status) {
    if (owner in this.statuses && status in this.statuses[owner]) {
      return this.statuses[owner][status];
    }

    return '';
  }

and in the html template something like:

<div data-bind="text: get_status('owner_1', 'api_call_1')"></div>

I hope this is understandable, but if it is not clear, here is (not) working example.

Advertisement

Answer

KnockoutJS observables are functions, thus to get their value they should be evaluated. In your case you just need to replace this.statuses to this.statuses() everywhere in the code where the value of observable is needed, like this:

set_status(owner, status, api_response) {
    if (!(owner in this.statuses())) this.statuses()[owner] = {};
    this.statuses()[owner][status] = api_response;
}

get_status(owner, status) {
    if (owner in this.statuses() && status in this.statuses()[owner]) {
        return this.statuses()[owner][status];
}

Also, the KnockoutJS observables does not track the object mutations, thus when mutating the value like below, it won’t be detected:

this.statuses()[owner][status] = api_response;

In such cases, after the mutation of value like above, the observable should be “notified” that it’s value has mutated, by calling the valueHasMutated method:

this.statuses.valueHasMutated();
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement