title: Knockout JS - foreach: data-bind not get refreshed
body: <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>