Search code examples
javascriptjsonknockout.jsknockout-mapping-plugin

Mapping multiple different JSON sources into one viewmodel with Knockout JS


I am trying to map multiple (different) JSON sources into one viewModel, but I can't seem to get it working.

I created a viewModel:

    var viewModel;

I created different mapping options like below:

    var mappingPerformedActions = {
        'PerformedActions': {
            key: function(data) {
                return ko.utils.unwrapObservable(data.Id);
            }
        }
    };

    var mappingEntities = {
        'Entities': {
            key: function(data) {
                return ko.utils.unwrapObservable(data.Id);
            }
        }
    };

Then I build my get function:

    get = function() {

        $.getJSON("localhost/urlWhichWorksWithSingleMapping", function(getdata) {
            viewModel = ko.mapping.fromJS(getdata, mappingEntities );
        });

        $.getJSON("localhost/anotherUrlWhichWorksWithSingleMapping", function(getdata) {
            ko.mapping.fromJS(getdata, mappingPerformedActions, viewModel);
        });

            ko.applyBindings(viewModel);
    };

get();

Then I try to loop trough Entities

<ul data-bind="foreach: BiztalkEntities">
    <li><span data-bind="text: Name"></span></li>
</ul>

This works with single sources

Note that all this works when I have just one source, so there are no mistakes in URLS or something. I have looked over stack overflow, but can't seem to find an example that fits my needs, I hope you could tell me what I am doing wrong here!


Solution

  • Have your viewModel with two different properties and map to those. Otherwise you need to merge data into single array:

    var viewModel = { PerformedActions: [], Entities: [] };

    Then assign received data:

       $.getJSON("localhost/urlWhichWorksWithSingleMapping", function(getdata) {
            viewModel.PerformedActions = ko.mapping.fromJS(getdata, mappingEntities );
        });
    
    
        $.getJSON("localhost/anotherUrlWhichWorksWithSingleMapping", function(getdata) {
            viewModel.Entities = ko.mapping.fromJS(getdata, mappingPerformedActions);
        });
    

    This is asynchronous, so at the time of binding you still don't have data. This is the best I can come up, it is not very clear where is the issue. Check console for errors, this will help you understand where the issue is.