1

I want to loop through an observableArray of objects and in this loop, I have to get the corresponding value of another observableArray. I do not succeed in doing this.

My code is as follow.

Model and viewmodel:

//**********MODEL********************
function Configuration() {
var self = this;

self.properties = ko.observableArray();
}

function deviceProperty() {
    var self = this;

    self.property = ko.observable("");
    self.value = ko.observable("");
}

//**********VIEWMODEL****************
function compareModelView() {
var self = this;

self.config1 = ko.observable(new Configuration);
self.config2 = ko.observable(new Configuration);

$().ready(function () {
    //Load config1 and config2
});

}

//**********jQuery********************
(function ($) {
    $(document).ready(function () {
        ko.applyBindings(new compareModelView());
    });
})(jQuery);

View:

<!-- ko foreach: config1().properties -->
     <tr>
     <td data-bind="text: property()"></td>
     <td data-bind="text: value()"></td>
     <td data-bind="text: $root.config2().properties()[$index].value()"></td>
     </tr>
<!-- /ko -->

Knockoutjs gives an error, saying that this property doesn't exist.

When I do $root.config2().properties().length it returns a number (3). When I do $root.config2().properties()[0] it returns [Object][Object]. When I do $root.config2().properties()[0] it returns an empty string.

But I can't see how I can directly address the value property inside the object?

4
  • Why do you want todo that? The view should be clean from code Commented Jun 11, 2013 at 11:37
  • @Anders Because I have this model and I want to make a compare screen between different configs. Commented Jun 12, 2013 at 6:56
  • 1
    But its more MVVM to move the code to the viewmdodel. Thats all im saying. Commented Jun 12, 2013 at 7:04
  • You are right, I know. But I'm having this objects generated on another page with an Ajax call. It is more MVVM to make a model wit propertyname, value1, value2. Commented Jun 12, 2013 at 7:44

1 Answer 1

1

$index is an observable property (see doc), so you need to write $index() to get its value.

So the following binding should work:

<td data-bind="text: $root.config2().properties()[$index()].value()"></td>

Although your main problem was the $index() but in itself it won't solve your case because the population order of the collections does matter in this scenario so you get errors with your current setup.

So if you populate first the config1() KO starts to bind your table but if the config2() has not been populated yet you will get the some undefined errors. To fix it you need change the population order to populate the config2() first.

You can play with this here: http://jsfiddle.net/xwjKK just change the order pupulateConfig2 and pupulateConfig1 call to see the effect.

Sign up to request clarification or add additional context in comments.

3 Comments

$root.config2().properties()[$index()].value() gives Message: TypeError: $root.config2(...).properties(...)[$index(...)] is undefined;. Howerver $root.config2().properties()[$index()] gives [object Object]. So correct for the $index(), but still can't address the value property.
The $root.config2().properties()[$index()].value() should work but if you populate first the config1() KO starts to populate your table but if the config2() has not been populated yet you get the is undefined message. So you need to populate config2 first. You can play with this here: jsfiddle.net/xwjKK just change the order pupulateConfig2 and pupulateConfig1 call to see the effect.
If you don't want to/cannot change the population order you can add some index checking with the with bindindg: jsfiddle.net/xwjKK/1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.