7

I am trying to map an array of objects to an observableArray with the knockout mapping plugin. Somehow this seems not to work for me at all.

I just tested with Crome console to verify:

ko.mapping.fromJS( [ { x: 1, y: "test" } ] )

returns:
[]

What am I doing wrong? If I try the following

ko.mapping.fromJS( [ { x:1, y: "test" } ][0] )

returns an object containing x and y as observables...

it all works well. The only difference is that I only deliver a single object instead of an array of objects. But if I read the documentation of the mapping plugin correctly, it should be able to handle creating an observableArray out of a normal array.

Thanks for your help,
Andreas

3
  • 7
    In Chrome's console make sure that you are looking at the unwrapped value of the observableArray myObservableArray(). It can be misleading when just printing out the observableArray itself. Commented Mar 11, 2012 at 17:52
  • 4
    As RP stated... you are just looking at the wrong value. Here is a fiddle that you can use to verify. Set a breakpoint on the ko.mapping line and type: ko.mapping.fromJS(data) and you'll see []. If you type: ko.mapping.fromJS(data)() and you see [Object, Object, Object, Object]. jsfiddle.net/jearles/y4b9e/8 Commented Mar 11, 2012 at 18:11
  • 1
    Thanks guys, Chrome tricked me by printing just [] which indicates an empty array. But you are absolutely right, if I but braces behind the expression it shows the contents allright. Great to get comments so soon! Stackoverflow rocks... Commented Mar 11, 2012 at 23:53

2 Answers 2

1

That's what it should be doing (at least in theory / documentation), but apparently that's not what it's doing. I am having same problem and I believe other too: https://groups.google.com/forum/?fromgroups=#!topic/knockoutjs/uKY84iZaxcs

The object must be:

{ "someName" : [ { x: 1, y: "test" } ] }

To stick with your object schema, you can use ko.utils.arrayMap to map object to your KO ViewModel: http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html

function Item(name, category, price) {
    this.name = ko.observable(name);
    this.category = ko.observable(category);
    this.price = ko.observable(price);
    this.priceWithTax = ko.dependentObservable(function() {
        return (this.price() * 1.05).toFixed(2);
    }, this);
}

//do some basic mapping (without mapping plugin)
var mappedData = ko.utils.arrayMap(dataFromServer, function(item) {
    return new Item(item.name, item.category, item.price);
});

EDIT

I did some more research on this and you CAN actually map JS array object with KO mapping, however, the after-map object is NOT going to be KO Observable Array. It will be just regular JS array object and, for that matter, you can data-bind with KO:

var bd = [ { x: 1, y: "bd test" }, { x: 2, y: "bd test 1dsf" } ];

var bdViewModel = ko.mapping.fromJS(bd);

// 'bdViewModel' is NOT KO Observable Array, so you can't use KO Binding. However, all the properties of 'bdViewModel' (x and y) are KO Observable.
//ko.applyBindings(bdViewModel, $("#bd").get(0));
console.log(bdViewModel());

// 'bdViewModel' must be called as function (with open and close parentheses) to see the data.
$.each(bdViewModel(), function (i, d) {
  $("#bdList").append("<li>" + d.y() + "</li>");
});

Here's the JSBin for comparison of mapping JS array and JSON: http://jsbin.com/uzuged/5/

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

1 Comment

Not using the mapping plugin worked in my case. I get an array of objects from the server and wanted to map it to an observable array. I used: self.MyObservArray(ko.utils.arrayMap(arrayfromServer, function (item) { return new BlogObject(item); }));
1
ko.mapping.fromJS(data, {}, self.items);

Comments

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.