Search code examples
knockout.jsknockout-mvc

Updating one observable property of knockout after ajax get


I am trying to implement a filtering in my knockout application using a AJAX get and i want to update only one of the many observables in the viewmodel. This is my viewmodel here in JS

function containerViewModel() {
mainViewModel = this;
mainViewModel.isBusy = ko.observable(false);
mainViewModel.errorMessage = ko.observable("");
mainViewModel.containerModel = ko.observable(
    {
        HomeSettings: ko.observable(),
        Employee: ko.observable(),
        Class: ko.observable(),
        Degree: ko.observable(),
        Specialization: ko.observable(),
        }
        );

    GET_AllContainer(mainViewModel);
}

Each of these observables are shown in different tabs and each tab has filter buttons. When i click the filter button from any tab, i fetch the data using ajax call. But the problem is am getting the whole data and binding to the viewmodel as this

function GET_FilteredContainer(mainView, filterText, productID, FilterID) {
mainViewModel.isBusy(true);
$.ajax({
    url: hostApi + api_GetAllContainer,
    contentType: "json",
    data: { FilterLinkIds: filterText, ProductID: productID },
    success: function (result) {
        mainView.containerModel(result);            
        SetFilterButtonCSS(productID, FilterID);
        ProductReportsNotFound(result);
        mainViewModel.isBusy(false);
    },
    error: function (result) {
        mainViewModel.errorMessage(result);
        mainViewModel.isBusy(false);
    }
});
}

But this means it will clear the filter of other tabs. So is there any way i can update only the required observable only

Can anyone help me.


Solution

  • well there are quite a few mistakes in code

    mainView.containerModel(result) is a Major one which you can't do because it will replace entire observable content as in you case it replaces observable's you have in your declaration(containerModel) rather filling those (as you may thought it would ) .

    viewModel:

    var ViewModel = function () {
        var self = this;
        self.containerModel = ko.observable({
            HomeSettings: ko.observable(),
            Employee: ko.observable(),
            Class: ko.observable(),
            Degree: ko.observable(),
            Specialization: ko.observable(),
        });
    
         var result = [{'HomeSettings':[1,2,3,4],'Employee':1}]
            console.log("Object you getting at ajax call success")
            console.log(result) //sample check
    
        console.log("correct way1 o/p")
        self.containerModel().HomeSettings(result[0].HomeSettings);
        self.containerModel().Employee(result[0].Employee);
        //like that for everything i.e see console everything is a function 
        console.log(self.containerModel())                                
    };
    ko.applyBindings(new ViewModel());
    

    sample working fiddle here

    PS: Advisable way would be like have a function written outside and declare you observable's in it . later you can use .map or mapping plugin to do your assigning in a neat flexible way to containerModel observable