0

I have added a few observable objects into an observableArray: dynaobs and they look like:

"dynaobs": [
    {
      "SpecName": "reportingcurrency",
      "SpecValue": "EUR"
    },
    {
      "SpecName": "transactionscurrency",
      "SpecValue": "GBP"
    }
  ]

I can view the values like below:

 <div class="col-sm-6" data-bind="foreach: { data: dynaobs, as: 'ct' }">        
        <input type="text" data-bind="value: ct.SpecValue" />       
</div>

However, I want to bind only the first index of my observableArray to an input control such as below, but it gives me an error:

<div data-bind="value: dynaobs()[0]">
    <input type="text" data-bind="value: $data" />
</div>

I have tried:

 <div data-bind="value: dynaobs()[0]">
        <input type="text" data-bind="value: $parent.SpecValue" />
    </div>

 <div data-bind="value: dynaobs[0]">
        <input type="text" data-bind="value: $parent.SpecValue" />
    </div>

and many more, but no luck. Any ideas?

EDIT: This is how I am adding the observables:

  for (var i = 0; i < data.specifications.length; i++) {
            if (data.specifications[i].controlname != null) {
               conv(data.specifications[i].controlname, data.specifications[i].specvalue);            
            }

        }

and calling:

function conv(lbl, val) {               
    this[lbl] = ko.observable(val);
    dynaobs.push(this[lbl]);
}
alwaysVBNET
  • 3,150
  • 8
  • 32
  • 65

1 Answers1

1

Is there a reason you bind the parent div value and then pass $data when you can just provide the value binding directly to the input?

var ViewModel = function() {
    this.arr = ko.observableArray([
    {
      "SpecName": "reportingcurrency",
      "SpecValue": "EUR"
    },
    {
      "SpecName": "transactionscurrency",
      "SpecValue": "GBP"
    }
  ])
}; 

ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div>
    <input type="text" data-bind="value: arr()[0].SpecValue" />
</div>
Akrion
  • 18,117
  • 1
  • 34
  • 54
  • I have tried that too! This should work but I get an error: jquery.js?cdv=108:3869 Uncaught TypeError: Unable to process binding "value: function(){return dynaobs()[0].SpecValue }" Message: Cannot read property 'SpecValue' of undefined – alwaysVBNET Jul 31 '18 at 18:49
  • The weird thing is when I do: I get [object Object] inside the input box!! – alwaysVBNET Jul 31 '18 at 18:50
  • So it works in the Example above but not on your end? Also you get [object Object] since you are trying to set an Object to a text box value so JS will unbox the object to a string ... which is `[object Object] – Akrion Jul 31 '18 at 18:52
  • yes, your example with your array aparently it works right. Just when I apply the same on my page, I get the error. The thing is since the object is bound, why can't I pull the SpecValue from it? – alwaysVBNET Jul 31 '18 at 18:53
  • What I am missing is why `value` binding to `div`? `value` binding is for input/select/textarea by the docs: http://knockoutjs.com/documentation/value-binding.html. So you are saying that even when you change to only value on your input html tag you still can properly access `arr()[0].SpecValue`? Is the code you posted above still current (in your first post)? – Akrion Jul 31 '18 at 19:15
  • Yes. I'm binding value to div as part of the million tests I did. No particular reason. Just trying to figure out what is wrong... – alwaysVBNET Jul 31 '18 at 19:40
  • I have added some code (see edit) to show how I am adding the observable objects to the array. Maybe that is problematic? Your answer is correct though and I will have to accept it. It just won't work for me... – alwaysVBNET Aug 01 '18 at 07:10
  • In that function `conv` ... can't you just do `dynaobs.push({ [lbl]: ko.observable(val) });`? Why do you need to set `this[lbl]`? – Akrion Aug 01 '18 at 07:19
  • And since you are dealing with an observable array do you need its elements to also be observable objects? – Akrion Aug 01 '18 at 07:19
  • Ideally what I would want is to have something like: that is generated from: "SpecName": "reportingcurrency", "SpecValue": "EUR". So, when I type a new currency the reportingcurrency will change the SpecValue. It seems I'm following the wrong approach. I'm accepting your answer regarding this, but do you have any ideas how would I tackle this problem? – alwaysVBNET Aug 01 '18 at 07:45
  • 1
    I would start simplifying as much as possible until you see where the issue resides. I would just have observableArray with values (not even objects) and see if it works that way ... then move to objects ... then to observable object etc. It seems issue is with the logic which composes your array values since in my example there is no issue to get that 0 index at all. – Akrion Aug 01 '18 at 07:53
  • 1
    problem was my two async functions. Being async it wouldn't let the other one complete that's why it was giving the null reference exception. Sigh... – alwaysVBNET Aug 01 '18 at 17:58