Unable to process binding "value: function() {return myVar }"

22 views Asked by At

I am using knockout.js and am trying to get a <select> tag to populate with options from on of the view model's properties. I think I did everything right but it breaks. The console error is

Uncaught ReferenceError: Unable to process binding "value: function(){return myArray } at value (eval at parseBindingsString, :3:237)"

My Code:

js

var MyViewModel = function () {
    var self = this;
    self.myArray = ko.observableArray([
        { text: 'First Item', value: '1' },
        { text: 'Second Item', value: '2' }
    ]);
}

cshtml

<div style="flex-basis: 100%;">
    <ul data-bind="foreach: ThisArray">
        <li>
            <select data-bind="options: myArray, optionsText: 'text', optionsValue: 'value', optionsCaption: 'Select item', value: degreeType"></select>
        </li>
    </ul>
</div>

I feel like I'm using the right syntax. Not sure why I'm getting this error. Anyone got any ideas?

1

There are 1 answers

0
Nathan Fisher On

There are a couple of things that I can see going on here. The first is that in the example javascript provided there is no ThisArray to match the foreach binding on the ul. Another issue is that there is no degreeType in the MyViewModel.

One problem I think you are having with knockout is recognising changes in context boundaries in the HTML. Knockout Binding context documentation Hopefully the following examples are able to help.

var MyViewModel = function () {
    var self = this;
    self.myArray = ko.observableArray([
        { text: 'First Item', value: '1'},
        { text: 'Second Item', value: '2' }
    ]);
    self.selectedValue = ko.observable();
}


var PageModel = function(){
  var self = this;
  self.ThisArray = ko.observableArray([new MyViewModel(), new MyViewModel(),]);
}

let model = new PageModel();

ko.applyBindings(model);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"></script>
 <div style="flex-basis: 100%;"> <!-- PageModel context -->
    <ul data-bind="foreach: ThisArray"> <!-- PageModel context -->
        <li> <!-- MyViewModel context  -->
            <select data-bind="options: myArray, optionsText: 'text', optionsValue: 'value', optionsCaption: 'Select item', value: selectedValue"></select>
        </li> <!-- MyViewModel context  -->
    </ul> <!-- PageModel context  -->
</div> <!-- PageModel context -->

<pre data-bind="text: ko.toJSON($data)"></pre>

if you need to reference a property on a parent context then you can use $parent or $parents[0]

var MyViewModel = function() {
  var self = this;
  self.selectedValue = ko.observable();
}


var PageModel = function() {
  var self = this;
  self.ThisArray = ko.observableArray([new MyViewModel(), new MyViewModel(), ]);

  self.myArray = ko.observableArray([
    { text: 'First Item', value: '1'},
    { text: 'Second Item', value: '2'}
  ]);
}

let model = new PageModel();

ko.applyBindings(model);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"></script>
<div style="flex-basis: 100%;">
  <!-- PageModel context -->
  <ul data-bind="foreach: ThisArray">
    <!-- PageModel context -->
    <li>
      <!-- MyViewModel context  -->
      <select data-bind="options: $parent.myArray, optionsText: 'text', optionsValue: 'value', optionsCaption: 'Select item', value: selectedValue"></select>
    </li>
    <!-- MyViewModel context  -->
  </ul>
  <!-- PageModel context  -->
</div>
<!-- PageModel context -->

<pre data-bind="text: ko.toJSON($data)"></pre>