Search code examples
javascriptknockout.jsknockout-2.0knockout-3.0

knockoutjs call keeps executing, how can I call it only once?


I have this piece of code:

t._teacherOptions = ko.observable();

function getTeacherList() {
  $.ajax({
    type: "POST",
    url: "/webservices/Service.asmx/GetTeachers",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(i) {
      if (i.d) {
        console.log(i.d);
        return t._teacherOptions(i.d);

      }
    },
    error: function(n) {
      u(n);
    }
  });
}

t.TeacherOptions = ko.computed(function() {
  getTeacherList();
  return t._teacherOptions();
});

And then my html:

<select data-bind="options: $root.TeacherOptions(), value: Id, optionsText: 'Name'"></select>

For some reason, when the page is opened, the function for getting the teacher list is continuously looping without stop.

I'm able to get the results I need but the loop keeps going and I need to stop that. Anything wrong I'm doing here?


Solution

  • You're looping endlessly because your TeacherOptions (which is a computed) accesses _teacherOptions (hence creating a dependency) and since you're mutating the value of _teacherOptions in the success callback of your Ajax call, the TeacherOptions is being evaluated again (because it depends on _teacherOptions) and issues the Ajax request again.

    Try to call getTeacherList() outside of your computed:

    t._teacherOptions = ko.observable();
    
    function getTeacherList() {
      $.ajax({
        type: "POST",
        url: "/webservices/Service.asmx/GetTeachers",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(i) {
          if (i.d) {
            console.log(i.d);
            return t._teacherOptions(i.d);
    
          }
        },
        error: function(n) {
          u(n);
        }
      });
    }
    
    getTeacherList();
    
    t.TeacherOptions = ko.computed(function() {
      return t._teacherOptions();
    });
    

    See Documentation