title: Knockout mapping and foreach data-bind on table with buttons, missing reference to viewmodel?
body: <p>I use mvc4 and entityframework in combination with knockout. I also use knockout mapping. But I run into a problem wich I cannot get solved.</p>
  
  <p>What I want to achieve:</p>
  
  <ul>
  <li>User clicks on delete button to delete row from table. [<strong>Works</strong>]</li>
  <li>Call the delete action method on the mvc controller to actualy delete the data from the
  database. [<strong>Works</strong>]</li>
  <li>Send back new Json object containing the data of the new changed
  table. [<strong>Works</strong>]</li>
  <li>Load the new data in my knockout viewmodel and update the UI using <code>ko.mapping.fromJS() and ko.applyBindings()</code> <strong>[Does not
  work and I am realy lost here</strong>]</li>
  </ul>
  
  <p>It looks like I totaly lost the reference to my list of Experiences wich I use to databind and foreach my table with. And I think it has to do with the way I call my deletemethod from within the foreach loop.</p>
  
  <p>It also looks like the javascript 'trick' with var <code>self = this;</code> doesnt work to get my reference to the correct data.</p>
  
  <p>Here follows my code I use for now to give you all a better idea of the situation. If more information is needed please let me know.</p>
  
  <p>These are my mvc viewmodels:</p>
  
  <pre><code>public class ExperienceOverviewModel
  {
          public ExperienceModel selectedExperience { get; set; }
          public List&lt;ExperienceModel&gt; Experiences { get; set; }
  }
  
  public class ExperienceModel
  {
          public int ExperienceId { get; set; }
          public DateTime DateFrom { get; set; }
          public DateTime DateUntil { get; set; }
          public string Description { get; set; }
          public string Employer { get; set; }
          public decimal Hours { get; set; }
          public int PersonId { get; set; }
          public bool? Secondment { get; set; }
          public string Title { get; set; }
  }
  </code></pre>
  
  <p>This is my table where I foreach databind the experiences using knockout:</p>
  
  <pre><code>&lt;/table&gt;
      &lt;thead&gt;
          &lt;/thead&gt; 
      &lt;tbody data-bind="foreach: Experiences()"&gt;
              &lt;tr&gt;
                  &lt;td data-bind="text: Employer"&gt;&lt;/td&gt;
                  &lt;td data-bind="text: Description"&gt;&lt;/td&gt;
                  &lt;td data-bind="text: DateFrom"&gt;&lt;/td&gt;
                  &lt;td data-bind="text: DateUntil"&gt;&lt;/td&gt;
                  &lt;td data-bind="text: Secondment"&gt;&lt;/td&gt;
                  &lt;td&gt;
                      &lt;a href="#" data-bind="click: function(data, event){ $root.EditExperienceModal(data); }"&gt;&lt;i class="icon-edit"&gt;&lt;/i&gt;&lt;/a&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                      &lt;a href="#" data-bind="click: function(data, event){ $root.ConfirmDeleteExperienceModal(data);}"&gt;&lt;i class="icon-remove"&gt;&lt;/i&gt;&lt;/a&gt;
                  &lt;/td&gt;
              &lt;/tr&gt;
          &lt;/tbody&gt;
      &lt;/table&gt;
  </code></pre>
  
  <p>My knockout viewmodel where I want to call ko.mapping.fromJS() and ko.applyBindings()... Here it goes fubar....</p>
  
  <pre><code>    function ViewModel() {
              this.DeleteExperience = function (experience) {
  
                  $.ajax({
                      type: "post",
                      contentType: "application/json",
                      url: "/Experienced/Delete/" + this.selectedExperience.ExperienceId(),
                      data: ko.toJSON(self.selectedExperience),
                      error: function (xhr, status, error) {
                      },
                      success: function (response) {
  
                          ko.mapping.fromJS(response, ?? this.Experiences ??);  &lt;---- ???
                          ko.applyBindings(?????);                              &lt;---- ???
  
                      }
                  });
              }
          }
  
          $(function () {
              var jsonModel = '@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model, new Newtonsoft.Json.Converters.IsoDateTimeConverter()))';
              var mvcModel = ko.mapping.fromJSON(jsonModel);
  
              var myViewModel = new ViewModel();
              g = ko.mapping.fromJS(myViewModel, mvcModel);
              ko.applyBindings(g);
          });
  </code></pre>
  
  <p><em><strong></em>* -- UPDATED -- <em>*</em></strong></p>
  
  <p>To clarify more here is what I have simplyfied:
  When I get the results back from the AJAX call I get the following error:</p>
  
  <blockquote>
    <p>Object # has no method 'Experiences'</p>
  </blockquote>
  
  <pre><code>&lt;table class="table table-striped"&gt;
      &lt;tbody data-bind="foreach: Experiences()"&gt;
          &lt;tr&gt;
              &lt;td data-bind="text: Employer"&gt;&lt;/td&gt;
              &lt;td data-bind="text: Description"&gt;&lt;/td&gt;
              &lt;td data-bind="text: DateFrom"&gt;&lt;/td&gt;
              &lt;td data-bind="text: DateUntill"&gt;&lt;/td&gt;
              &lt;td data-bind="text: Secondment"&gt;&lt;/td&gt;
              &lt;td&gt;
                 &lt;a href="#" data-bind="click: $root.DeleteExperience"&gt;&lt;i class="icon-remove"&gt;&lt;/i&gt;&lt;/a&gt;
  
              &lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
  &lt;/table&gt;
  &lt;script type="text/javascript"&gt;
  
      function ViewModel() {
          var self = this;
  
          self.DeleteExperience = function (experience) {
              $.ajax({
                  type: "post",
                  contentType: "application/json",
                  url: "/Experienced/Delete/" + experience.ExperienceId(),
                  data: ko.toJSON(experience),
                  error: function (xhr, status, error) {
                      console.log(error);
                  },
                  success: function (response) {
                      $('#confirmDeleteModal').modal('hide');
                      self.UpdateExperienceList(response);
                  }
              });
          }
  
          self.UpdateExperienceList = function (data) {
              self.Experiences(data);       &lt;---- ?????
          }
      }
  
      $(function () {
          var jsonModel = '@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model, new Newtonsoft.Json.Converters.IsoDateTimeConverter()))';
          var mvcModel = ko.mapping.fromJSON(jsonModel);
          var myViewModel = new ViewModel();
          g = ko.mapping.fromJS(myViewModel, mvcModel);
          ko.applyBindings(g);
      });
  &lt;/script&gt;
  </code></pre>