Knockout JS - foreach: data-bind not get refreshed
<p>SPEC : Building a customer support application.</p>

<p>First time, when a user send a message able to save to DB and show in the view without any issues. And from my end, if i send I am able to push the data to the UI as well DB and the user is able to get the message.</p>

<p>But the issue is when the user send back response again, its not showing up refreshing the UI.</p>

<p>Below is my knockout code,</p>

<pre><code>var csendpoints = {
"Active": "/cs/oc/",
"ActiveClientData": "/cs/gnm/",
"Archive": "/cw/archive/",
"Dequeue": function (id) { return "/cw/dequeue/" + id; },
"GetQueue": "/cs/q/",
"GetArchive": "/cs/h/",
"GetActive": "/cs/active/",
"RecentlyQueued": "/cs/rq/",
"Send": "/cs/send",
"SitRep": "/cw/sitrep",
};
var customerSupportViewModel;

 function PagedViewModels(model) {
var self = this;
self.Items = ko.observableArray(model.Items || []);
self.MetaData = ko.observable(model.MetaData || "");
}

function PagedListMetaDataViewModel(model) {
var self = this;
self.FirstItemOnPage = ko.observable(model.FirstItemOnPage || "");
self.HasNextPage = ko.observable(model.HasNextPage || "");
self.HasPreviousPage = ko.observable(model.HasPreviousPage || "");
self.IsFirstPage = ko.observable(model.IsFirstPage || "");
self.IsLastPage = ko.observable(model.IsLastPage || "");
self.LastItemOnPage = ko.observable(model.LastItemOnPage || "");
self.PageCount = ko.observable(model.PageCount || "");
self.PageNumber = ko.observable(model.PageNumber || "");
self.PageSize = ko.observable(model.PageSize || "");
self.TotalItemCount = ko.observable(model.TotalItemCount || "");
}

function ConversationMessageViewModels(model) {
var self = this;
self.ClientId = ko.observable(model.ClientId || "");
self.ClientName = ko.observable(model.ClientName || "");
self.ClientSex = ko.observable(model.ClientSex || "");
self.ClientLanguage = ko.observable(model.ClientLanguage || "");
self.ClientProvince = ko.observable(model.ClientProvince || "");
self.ClientCountry = ko.observable(model.ClientCountry || "");
self.ClientCity = ko.observable(model.ClientCity || "");
self.ClientProfileImage = ko.observable(model.ClientProfileImage || "");
self.ClientContent = ko.observable(model.ClientContent || "");
self.Content = ko.observable(model.Content || "");
self.ConversationMessageId = ko.observable(model.ConversationMessageId ||     "");
self.dummy = ko.observable();
self.Sender = ko.observable(model.Sender || "");
self.SentOn = ko.observable(model.SentOn || "");
self.SentOnUniversalSortable = ko.observable(model.SentOnUniversalSortable || "");
self.SentTimeFromNow = ko.computed(function () {
    self.dummy();
    return moment.utc(self.SentOnUniversalSortable()).fromNow();
});


function updateTimeFromNow() {
    setTimeout(function () {
        self.dummy.notifySubscribers();
        updateTimeFromNow();
    },
        60 * 1000);
}

updateTimeFromNow();
}

function ConversationViewModels(model) {
var self = this;
self.ClientId = ko.observable(model.ClientId || "");
self.ClientName = ko.observable(model.ClientName || "");
self.ClientProfileImage = ko.observable(model.ClientProfileImage || "");
self.ClientSex = ko.observable(model.ClientSex || "");
self.ClientLanguage = ko.observable(model.ClientLanguage || "");
self.ClientProvince = ko.observable(model.ClientProvince || "");
self.ClientCountry = ko.observable(model.ClientCountry || "");
self.ClientCity = ko.observable(model.ClientCity || "");
self.ClientNameInitial = ko.observable(model.ClientName.substring(0, 1).toUpperCase());
self.ClientContent = ko.observable(model.ClientContent || "");
self.ConversationId = ko.observable(model.ConversationId || "");
self.CreatedOn = ko.observable(model.CreatedOn || "");
self.MessagePreview = ko.observable(model.MessagePreview || "");
self.Messages = ko.observableArray([]);
self.ProfileImageUrl = ko.observable(model.ProfileImageUrl || "");
self.Sender = ko.observable(model.Sender || "");
self.SupportName = ko.observable(customerSupportViewModel.CustomerSupportName());
self.TextBoxContent = ko.observable("");
self.TextBoxEnabled = ko.observable(true);

self.MakeActive = function () {
    customerSupportViewModel.WaitingList.remove(self);
    customerSupportViewModel.ArchivedConversations.remove(self);
    customerSupportViewModel.ActiveConversation(self);
    customerSupportViewModel.CurrentConversations.push(self);
    $.ajax(csendpoints.Active + self.ConversationId(),
    {
        success: console.log("Debug: Now Active")
    });
};

self.MakeRemoveMultiActive = function () {
    customerSupportViewModel.WaitingList.remove(self);
    customerSupportViewModel.ArchivedConversations.remove(self);
    customerSupportViewModel.ActiveConversation(self);
    //customerSupportViewModel.CurrentConversations.push(self);
    //customerSupportViewModel.CurrentConversations.remove(self);
    $.ajax(csendpoints.Active + self.ConversationId(),
    {
        success: console.log("Debug: Now Active")
    });
    $("#chat-wrap").mCustomScrollbar("destroy");
    $("#chat-wrap").height($(window).height() - 314);
    $("#chat-wrap")
           .mCustomScrollbar({
               axis: "y",
               scrollEasing: "linear",
               scrollButtons: { enable: true },
               theme: "dark-thick",
               scrollbarPosition: "inside",
               mouseWheelPixels: 400
           });
    initMap()
};
self.Archive = function () {
    customerSupportViewModel.ArchivedConversations.push(self);
    customerSupportViewModel.ActiveConversation('');
    customerSupportViewModel.CurrentConversations.remove(self);
    customerSupportViewModel.WaitingList.remove(self);

    customerSupportViewModel.RefreshWaiting();
    customerSupportViewModel.RefreshActive();
    customerSupportViewModel.RefreshArchive();
    $.ajax(csendpoints.Archive + self.ConversationId(),
    {
        success: console.log("Debug: Now Archived")
    });
};
self.SendMessage = function (data) {
    self.TextBoxEnabled(false);
    var msj = {
        "SentOn": moment.utc().format(),
        "SentOnUniversalSortable": moment().format(),
        "Sender": 1,
        "SenderName": customerSupportViewModel.CustomerSupportName(),
        "Content": self.TextBoxContent(),
        "ClientId": self.ClientId(),
        "ClientName": self.ClientName()
    };

    self.Messages.push(new ConversationMessageViewModels(msj));
    $.ajax({
        type: "POST",
        url: csendpoints.Send,
        data: $(data).serialize(),
        success: function () { },
        complete: function () {
            self.TextBoxContent("");
            self.TextBoxEnabled(true);
        }
    });
};


_.each(model.Messages, function (item) {
    self.Messages.push(new ConversationMessageViewModels(item));
});
var sortedMessages = _.sortBy(self.Messages(),
    function (iteratedItem) { return iteratedItem.SentOnUniversalSortable(); });
self.Messages(sortedMessages);

}


function CustomerSupportViewModel(model) {
var self = this;
customerSupportViewModel = self;

function getWaitingList(page) {
    $.ajax(csendpoints.GetQueue + page,
    {
        success: function (data) {
            self.WaitingList.removeAll();

            _.each(data.Items, function (item) { self.WaitingList.push(new ConversationViewModels(item)); });

            self.WaitingListPaging(data.MetaData);
        }
    });
}

function getActiveList(page) {
    $.ajax(csendpoints.GetActive + page,
    {
        success: function (data) {
            self.CurrentConversations.removeAll();

            _.each(data.Items, function (item) { self.CurrentConversations.push(new ConversationViewModels(item)); });

            self.CurrentConversationsPaging(data.MetaData);
        }
    });
}

function getArchiveList(page) {
    $.ajax(csendpoints.GetArchive + page,
    {
        success: function (data) {
            self.ArchivedConversations.removeAll();

            _.each(data.Items, function (item) {
                self.ArchivedConversations.push(new ConversationViewModels(item));
            });

            self.ArchivedConversations(data.MetaData);
        }
    });
}


// Conversations in Queue(i.e. waiting), Current(i.e. active) and Archive (i.e. history)
self.WaitingList = ko.observableArray([]);
self.ArchivedConversations = ko.observableArray([]);
self.CurrentConversations = ko.observableArray([]);

// Paging models
self.WaitingListPaging = ko.observable(model.ConversationsInQueue.MetaData);
self.ArchiveListPaging = ko.observable(model.ArchivedConversations.MetaData);
self.CurrentConversationsPaging = ko.observable(model.CurrentConversations.MetaData);

// The conversation currently active.
self.ActiveConversation = ko.observable();
//setInterval(self.ActiveConversation, 500);
// The name of the WeChatAccount serving the client
self.CustomerSupportName = ko.observable(model.CustomerSupportName);


self.RefreshWaiting = function () {
    var page = self.WaitingListPaging().PageNumber;
    getWaitingList(page);
};
self.RefreshActive = function () {
    var page = self.CurrentConversationsPaging().PageNumber;
    getActiveList(page);
    //getWaitingList(page);
};
self.RefreshArchive = function () {
    var page = self.ArchiveListPaging().PageNumber;
    //getArchiveList(page);
    getWaitingList(page);
};
//self.RefreshChatActive = function () {
//    getActiveList()
//};

// ###### PAGING for Waiting / Queue ######
// Forward paging for the queue / waiting list
self.NextPageWaitingList = function () {
    if (self.WaitingListPaging().IsLastPage) return;
    var page = self.WaitingListPaging().PageNumber + 1;
    getWaitingList(page);
};
self.PreviousPageWaitingList = function (data, e) {
    //console.log($(data))
    //console.log((e.target) ? e.target : e.srcElement)

    if (self.WaitingListPaging().IsFirstPage) return;

    var page = self.WaitingListPaging().PageNumber - 1;
    getWaitingList(page);
};

//  ###### PAGING for Active / Current conversations ######
self.NextPageActiveList = function () {
    if (self.CurrentConversations().IsLastPage) return;
    var page = self.CurrentConversations().PageNumber + 1;
    getActiveList(page);
};
self.PreviousPageActiveList = function () {
    if (self.CurrentConversations().IsFirstPage) return;
    var page = self.CurrentConversations().PageNumber - 1;
    getActiveList(page);
};

//  ###### PAGING for History / Archived conversations ######
self.NextPageArchiveList = function () {
    if (self.ArchivedConversations().IsLastPage) return;
    var page = self.ArchivedConversations().PageNumber + 1;
    getArchiveList(page);
};
self.PreviousPageArchiveList = function (data, e) {
    if (self.ArchivedConversations().IsFirstPage) return;
    var page = self.ArchivedConversations().PageNumber - 1;
    getArchiveList(page);
};


_.each(model.ConversationsInQueue.Items,
    function (item) { self.WaitingList.push(new ConversationViewModels(item)); });
_.each(model.CurrentConversations.Items,
    function (item) { self.CurrentConversations.push(new ConversationViewModels(item)); });
_.each(model.ArchivedConversations.Items,
    function (item) { self.ArchivedConversations.push(new ConversationViewModels(item)); });


function getNewQueue(page) {
    setTimeout(function () {
        $.ajax(csendpoints.GetQueue + page,
        {
            success: function (data, odata) { getNewQueue(); }
        });
    },
        15 * 1000);
}
}

var customerSupportViewModel = new CustomerSupportViewModel(jsonViewModel);
window.setInterval(customerSupportViewModel.RefreshWaiting, 1000);
window.setInterval(customerSupportViewModel.RefreshActive, 200);
window.setInterval(customerSupportViewModel.Messages, 200);

ko.applyBindings(customerSupportViewModel);

var conversationMessageViewModels = new       ConversationMessageViewModels(jsonViewModel);
</code></pre>

<p>Here MakeRemoveMultiActive is used as a click function, and in the view, it load the data what user sent as well the response sent from my end. Note, this happens only on click event. </p>

<p>I want to update the UI after the click event so the view is open with the data and autoupdates.</p>

<p>Request experts to shed some light.</p>