Morten Nørgaard Morten Nørgaard - 2 months ago 11
Ajax Question

How to remove Knockout.js ObservableArray-object after ajax call

I'm trying to remove an object from an ObservableArray after an ajax-call. It works with the '.pop' function, but not when I'm using the custom knockout.js '.remove'-function.

If I move the call to the '.remove' function outside the ajax-complete function, '.remove' does work. But I would really rather have it inside the '.complete'.

Can anyone spot what I'm doing wrong?

This doesn't work:

self.removeItem = function(data) {

$.ajax({
type: 'POST',
url:'/echo/js/?js=hello%20world!',
dataType: 'json',
contentType: 'application/json',
data: null
}).complete(function (item,data) {
self.Items.remove(data);
});
};


I made a jsfiddle to demonstrate: http://jsfiddle.net/6oe6dn7n/1/

My view-model looks like so:

var data = {
Name: "Test",
Items: ["One", "Two", "Three"]
};

function ViewModel(data) {
var self = this;
self.Items = ko.observableArray(ko.utils.arrayMap(data.Items,

function(item) {
return { value: ko.observable(item) };
}));

self.removeItem = function(data) {

$.ajax({
type: 'POST',
url:'/echo/js/?js=hello%20world!',
dataType: 'json',
contentType: 'application/json',
data: null
}).complete(function (item,data) {
// This doesn't affect the observableArray.
// 'self.Items.pop(data) does, however.
self.Items.remove(data);
});
};
}


And my HTML looks like so:

<div>
<table>
<tbody data-bind="template: { name: 'itemTemplate', foreach: Items }"></tbody>
</table>
</div>
<script type="text/html" id="itemTemplate">
<tr>
<td>
<input data-bind="value: value" />
<a href="#" data-bind="click: $parent.removeItem">Remove Item</a>
</td>
</tr>
</script>

TSV TSV
Answer

You have replaced "data" variable object in the context of response handler:

was:

self.removeItem = function(data) { // <- data
    $.ajax({
        type: 'POST',
        url:'/echo/js/?js=hello%20world!',
        dataType: 'json',
        contentType: 'application/json',
        data: null
    }).complete(function (item, data)  { // <- another data overrides upper data
             // This doesn't affect the observableArray.
             // 'self.Items.pop(data) does, however.
             self.Items.remove(data); // <- what data to use???
    });
};

changed:

self.removeItem = function(data) { 
    $.ajax({
        type: 'POST',
        url:'/echo/js/?js=hello%20world!',
        dataType: 'json',
        contentType: 'application/json',
        data: null
    }).complete(function (item, data1)  { // another data - data1
             // This doesn't affect the observableArray.
             // 'self.Items.pop(data) does, however.
             self.Items.remove(data);
    });
};

I've updated the fiddle, it works for me - at least removes items.

Comments