Question

I have the following model defined in .NET:

 Public Class Request
  <Key()>
  Public Property RequestId As String
  Public Property Description As String
  Public Property InfoCards As List(Of InfoCard)
End Class

Public Class InfoCard
  <Key()>
  Public Property InfocardId As String
  Public Property Description As String
  Public Property RequestId As String
End Class

The ReqeuestId property on the InfoCard is so that EF Code First can generate the db. I then use the UpshotContext helper to generate the JavaScript model like so:

Html.UpshotContext(bufferChanges:= true) _
  .DataSource(Of UpshotTest.UpshotTest.RequestController)(Function(x) x.GetRequests()) _
  .ClientMapping(Of UpshotTest.Models.Request)("Request") _
  .ClientMapping(Of UpshotTest.Models.InfoCard)("InfoCard")

This generates all models nicely, and when I call refresh on the upshot dataSource, the data is retrieved as expected.

The problem I am facing is when I attempt to modify a property of a child object (e.q. Request.InfoCards(0).Description). Changing that value will trigger the change in the InfoCard, but not in the Request entity. So, calling Request.IsUpdated() will return false, whilst calling Request.InfoCards(0).IsUpdated() will return true.

Does upshot not know how to track changes in child entities? Or is it a problem with the mappings on the client side? So far I have tried several mappings:

  • mapping all properties manually:

    window.Request = function (initialData) {
        var self = this;
        self.RequestId = ko.observable(initialData.RequestId);
        self.Description = ko.observable(initialData.Description);
        self.InfoCards = ko.observableArray(ko.utils.arrayMap(initialData.InfoCards, function (data) {
           return new window.InfoCard(data);
        }));
    
        upshot.addEntityProperties(self, "Request:#UpshotTest.Models");
    };
    
  • using upshot.map:

    window.Request = function (initialData) {
        var self = this;
        upshot.map(initialData, upshot.type(Request), self);
    };
    
  • defining my own map function and passing it to upshot:

    window.Request = function (initialData) {
        var self = this;
        upshot.observability.configuration.map(initialData, upshot.type(Request), map, self);
    };
    

The mappings seem correct with all approaches, except the parent entity is not aware of modifications done in its children. Is child tracking even possible?

Was it helpful?

Solution

Okay, I found the issue in the end. As it turns out, this behavior was reproducible when a hierarchy of 3 nested entities existed (i.e. Request -> InfoCard -> InfoField. Modifying a value of the InfoField did not reflect in the parent entity.

After many hours of upshot debugging, I found the culprit to be the _addTrackingRecursive method in upshot.js. Replacing the obs.track(obj, this._getTracker(), this._entityType); call to obs.track(obj, this._getTracker(), type); solved the nested change tracking issue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top