anchor
anchor

Reputation: 1885

Passing nested knockout view model to controller

This is fleet management app in mvc EF and knockout , there are VEHICLES , DRIVERS and specific ROUTES that the drivers travel.

I have a situation where I would like to gather field values from three models nested within my view models into a single object and post it my backend via ajax. I want this to be triggered by clicking a button.

There is a problem is in my populateFleetInformation function. When I gather the field values from my various models, some of the observables are losing their values and appear as null.

The view model that attempts to make the ajax call

    function FleetViewModel() {
    var vvm = this;
    vvm.regNumber = ko.observable(0);
    vvm.make = ko.observable("");
    vvm.model = ko.observable("");
    vvm.RouteDetail = new RouteViewModel();
    vvm.SaveFleetInfo = function(item){
        if (!pageViewModel.isAuthenticated()) return;
        populateFleetInformation(item);
        $.when(postSecureData("/api/Fleet/", ko.toJSON(pageViewModel.FleetViewModel.RouteViewModel.RouteDriverViewModel)))
          .done(function () {   
              document.getElementById("save-Fleet-btn").innerHTML = "Saving...";
              setTimeout(function () { document.getElementById("save-fleet-btn").innerHTML = "Save" }, 2500);
              $.msgGrowl({
                  type: 'info',
                  title: 'Fleet Information',
                  text: 'fleet information succesfully saved',
                  position: 'bottom-right',
                  lifetime: 3000
              });

          })

    }

}

function that gathers data

function PopulateFleetInformation(item)
{
    pageViewModel.fleetVM.regNumber(item.regNumber);
    pageViewModel.fleetVM.make(item.make);
    pageViewModel.fleetVM.model.(item.model);
    pageViewModel.fleetVM.routeDetail.routeID(item.routeId);
    pageViewModel.fleetVM.routeDetail.routeName(item.routeName);
    pageViewModel.fleetVM.routeDriver.nationalId(item.nationalId);
    pageViewModel.fleetVM.individualMsisdn.licenseId(item.licenseId);
    pageViewModel.fleetVM.individualMsisdn.driverName(item.driverName);

}

The trigger button

 <button type="submit" id="save-fleet-btn" class="btn"data-bind="click: $root.fleetVM.sensorDetail.SaveFleetInfo"></button>

Upvotes: 0

Views: 78

Answers (1)

Anish Patel
Anish Patel

Reputation: 4392

This function:

function PopulateFleetInformation(item)
{
    pageViewModel.fleetVM.regNumber(item.regNumber);
    pageViewModel.fleetVM.make(item.make);
    pageViewModel.fleetVM.model.(item.model);
    pageViewModel.fleetVM.routeDetail.routeID(item.routeId);
    pageViewModel.fleetVM.routeDetail.routeName(item.routeName);
    pageViewModel.fleetVM.routeDriver.nationalId(item.nationalId);
    pageViewModel.fleetVM.individualMsisdn.licenseId(item.licenseId);
    pageViewModel.fleetVM.individualMsisdn.driverName(item.driverName);

}

is not doing what you think it is at all.

itemis coming from the context passed into SaveFleetInfo by knockout when your button is clicked. This function is then setting the values of the fields you are trying to retrieve to whatever is in item; I'm guessing you're getting all sorts of undefined exceptions here.

What you want to do is this:

function PopulateFleetInformation() 
{ 
   return { 
      regNumber: pageViewModel.fleetVM.regNumber(); 
      make: pageViewModel.fleetVM.make(); 
      model: pageViewModel.fleetVM.model.(); 
      routeId: pageViewModel.fleetVM.routeDetail.routeID(); 
      routeName: pageViewModel.fleetVM.routeDetail.routeName(); 
      nationalId: pageViewModel.fleetVM.routeDriver.nationalId(); 
      licenseId: pageViewModel.fleetVM.individualMsisdn.licenseId(); 
      driverName: pageViewModel.fleetVM.individualMsisdn.driverName(); 
    } 
}

This function returns the values you are after as an object, then you can post this data like this:

    var data = populateFleetInformation();
    $.when(postSecureData("/api/Fleet/", ko.toJSON(data)))

Upvotes: 1

Related Questions