1

Fiddle here

I have an array of objects that I want to map directly into a collection on my viewmodel, but I want to customise the mapping. The code doesn't work though unless there is only one item in the data.UserReports collection.

I can do it if I add another layer into the object graph - so for instance instead of mapping data.UserReports to model.UserReports - if I had a property on the model called Foo - I could map data to foo and then access the collection via model.Foo.UserReports, but this is undesirable and messy.

I also reckon I can do it if i iterate through the data.UserReports array, and push each UserReport in turn onto the model's collection - but again this seems clumsy.

So what's wrong with the fiddle?

2 Answers 2

1

The code in that fiddle is not working at all, at least not for me. But however, here is how you would normally use the mapping plugin with an existing view model instance:

function PageModel() { /* ... */ }

$(document).ready(function() {
    var model = new PageModel();

    // Don't replace some observable, but extend the view model automatically,
    // creating an observable for each property in "data".
    ko.mapping.fromJS(data, userReportMapping, model);

    ko.applyBindings(model);
}​);​

http://jsfiddle.net/Quu4f/27/


Update: You also need to / should specify to which key in the data object the mapping options should be applied:

var userReportMapping = {
   'UserReports': {
        key: function(data) {
            return ko.utils.unwrapObservable(data.Id);
        },
        create: function(options) {
            return new userReportModel(options.data);
        }
    }
};

It is however a bit weird that you get an error when you have two items with the same ID in the data set. It seems as if the "create" callback is not executed for the duplicate, but a normal observable is still created.

http://jsfiddle.net/Quu4f/29/

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

4 Comments

makes no difference with the mapping as shown - it doesn't work as required - see my "answer" above for working code that gets the job done, but is not (imo) ideal
Sorry - needed to be clearer - of course the code you've posted works - the issue I'm struggling with is how to customise the mapping to handle an array.
@BonyT Alright, didn't get that right away. Found another bit and updated my answer - but I'm still not quite sure if that's what you're looking for now.
Ah - the two items should have different keys. But thanks - yes that's the missing piece - you hand the mapping code an object containing the array - and set the mapping code to process the Outer Object. Perfect - thanks for that.
0

This is doing it by iterating through the array and pushing each item in turn onto the observable collection - is there a better way?

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.