Search code examples
knockout.jsknockout-mapping-plugin

Knockout add new row to list of records mapping plugin


I'm using mapping plugin for updating view model like so:

        $.ajax({
            type: "POST",
            url: url,
            data: data,
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (json) {
                if (json.Page == 1) {
                    ko.mapping.fromJS(json, {}, self);
                } else {
                    self.List().push(ko.mapping.fromJS(json.List));
                }
                console.log(ko.toJSON(self.List()));
            },
        });

however instead of updating a List() observable array (adding only NEW items when ajax call completes - for page 2 (next several items from DB), it adds a new List => Notice "[" element in the console output:

AJAX response (json)

{"DiscountType":"Transaction","List":[{"ActivationDate":"/Date(1427215761818)/","CustomerName":"Another two 2","CustomerNumber":4328,"Percent":20,"HasDiscount":true},{"ActivationDate":"/Date(1428079761818)/","CustomerName":"Another tree","CustomerNumber":1212,"Percent":20,"HasDiscount":true}],"Page":2}

Console Output:

[{"ActivationDate":"/Date(1388556000000)/","CustomerName":"Test1 Inc.","CustomerNumber":10032,"Percent":20,"HasDiscount":true},{"ActivationDate":"/Date(1426783761818)/","CustomerName":"Another One 1","CustomerNumber":5174,"Percent":20,"HasDiscount":true},[{"ActivationDate":"/Date(1427215761818)/","CustomerName":"Another two 2","CustomerNumber":4328,"Percent":20,"HasDiscount":true},{"ActivationDate":"/Date(1428079761818)/","CustomerName":"Another tree","CustomerNumber":1212,"Percent":20,"HasDiscount":true}]]

what am i doing wrong?


Solution

  • To push the individual elements of your returned array, do something like

    success: function (json) {
        if (json.Page == 1) {
            ko.mapping.fromJS(json, {}, self);
        }
        else {
            json.List.forEach( 
                function(element) {
                   self.List.push( ko.mapping.fromJS(element) );
                } );
            }
        console.log(ko.toJSON(self.List()));
            }
    

    var vm = function() {
      var self = this;
      self.List = ko.observableArray([]);
      self.initiate = function() {
        json = JSON.parse('{"DiscountType":"Transaction","List":[{"ActivationDate":"/Date(1427215761818)/","CustomerName":"Another two 2","CustomerNumber":4328,"Percent":20,"HasDiscount":true},{"ActivationDate":"/Date(1428079761818)/","CustomerName":"Another tree","CustomerNumber":1212,"Percent":20,"HasDiscount":true}],"Page":2}');
        json.List.forEach(function(entry) {
          self.List.push(ko.mapping.fromJS(entry));
        });
      };
    };
    vm = new vm();
    ko.applyBindings(vm);
    vm.initiate();
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    
    <script src='https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js'></script>
    <html>
    
    <div data-bind='foreach: List'>
      <div data-bind='text: ActivationDate'></div>
    </div>
    
    </html>