0
votes

Trying to add an item to an observableArray in knockout. While the item is certainly being added to the view model, it is not being added to the view. Seems to be something to do with using ko.mapping.fromJS. Recreated the problem I am facing here:

function ViewModel() {
    var vm = {
        props: ko.observableArray(["A", "B"]),
        field: ko.observable(""),
        val: "Some value"
    };

    vm.field.subscribe(function () {
        vm.props.push("C");
    });

    return vm;
}

var myVM = new ViewModel();
myVM = ko.mapping.fromJS(myVM);
ko.applyBindings(myVM, document.getElementById("c"));

HTML:

<div id="c">
  <select data-bind="options: props"></select>
  <input data-bind="value: field">
  <span data-bind="text: val"></span>
</div>

When you enter something into the text box the drop down list does not update.

Fiddle: https://jsfiddle.net/GarryPas/3dmuLv92/3/

2

2 Answers

1
votes

The problem is with your "myVar = ko.mapping" line. Here is the proper way to map JSON into a pre-existing viewModel:

ko.mapping.fromJS(jsonToBeMapped, observableToMapJsonInto);

Knowing this, replace your "myVar = ko.mapping" line with the below:

ko.mapping.fromJS(myVM, myVM);

It now works as you expect, even though it looks funny because there is really no reason to be mapping an entire view model into itself. You could get rid of that line completely and get the same result.

Working Fiddle: https://jsfiddle.net/dw1284/yf8mmk1u/

0
votes

You don't need to use Mapping here since you have already defined observable variables in your model. What the mapping plugin does is it creates a mapping from the regular JavaScript object (or JSON structure) to an observable view model. So if you have a complex Object you don't need to define observable variables for all of your data. Mapping plugin does the job for you. But here you don't need to use it.

Remember whenever you subscribe to an observable you need to pass a parameter (newValue) in call back function in order to get the updated value from.https://jsfiddle.net/3dmuLv92/4/

function ViewModel() {
  var vm = {
    props : ko.observableArray(["A","B"]),
    field: ko.observable(""),
    val: "Some value"
  };

  vm.field.subscribe(function(newValue) {

    vm.props.push(newValue);
  });

  return vm;
}

var myVM = new ViewModel();
ko.applyBindings(myVM, document.getElementById("c"));