2

observable array not reflecting data on binding the output of webapi. where as it reflects data on binding hard-coded array. what is wrong in the code function GetAllCustomers.

function CustomerDataModel() {

    this.customerList = ko.observableArray([
    { FirstName: "John" },
        { FirstName: "Sam" },
        { FirstName: "Peter" },
        { FirstName: "Vicky"},
        { FirstName: "Amar" }
    ]);        


    this.GetAllCustomers = function () {

        $.ajax({
            url: 'http://localhost/komvc/api/customer',
            type: 'GET',
            dataType: 'json',
            contentType: 'application/json',
            success: function (data) {

                var mappedCusts = $.map(data, function (item) { return { FirstName: item.FirstName }; });
                console.log(mappedCusts[0].FirstName);
                this.customerList = ko.observableArray(this.mappedCusts);
                console.log(JSON.stringify(ko.toJS(this.customerList)));
            },
            error: function (x, y, z) {
                alert(x + '\n' + y + '\n' + z);
            }
        });        
    };
};
ko.applyBindings(new CustomerDataModel());

//html

<div>

    <div data-bind="foreach: customerList">
        <br />
        <span data-bind='text: FirstName' />
    </div>

    <button id="btnGet" data-bind="click:GetAllCustomers">Get All Customers</button>
</div>

//my web api is returning

{"Id":1,"FirstName":"Rakesh","LastName":"Suresh","Phone":"919239123","Address":"Bangalore"}
nemesv
  • 133,215
  • 15
  • 395
  • 348
user3651810
  • 109
  • 10

1 Answers1

2

With the call:

this.customerList = ko.observableArray(this.mappedCusts);

You are overriding your customerList with a completely new observable array which breaks the KO bindings.

What you need to do is to update the already existing customerList with:

this.customerList(mappedCusts);

You also need to fix your this handling because inside the success handler this definitely won't be your viewmodel object...

So you need to use the context: this, option on your ajax call:

$.ajax({
   //...
   context: this,
   success: function (data) {
    //this now refers to the same object as this in GetAllCustomers 
   }
});

Or you can store a reference to the correct this as described: var self = this? or use the bind function, etc.

Demo JSFiddle.

By the way your API is responding with a single object and not an array. Make sure that you calling the correct URL which returns an array, something like:

[{"Id":1,"FirstName":"Rakesh","LastName":"Suresh","Phone":"919239123","Address":"Bangalore"}]
Community
  • 1
  • 1
nemesv
  • 133,215
  • 15
  • 395
  • 348