Breeze Extended Entity Property Only Loads on Second Query
Asked Answered
B

2

1

Hopefully someone has a better insight into Breeze's Extended entities, because I'm stumped! So, I have created a partial class (WO_Rout) on the server side (Web API using Breeze's API) and created a property named "AssetJobEqNo".

I have read and followed Breeze's documentation here with no avail. Following the guide I have created a constructor for this particular entity "WO_Rout" like so:

var assets = function () {
    this.AssetJobEqNo = '';
};
var serviceName = 'cms8/workorders';
var manager = new breeze.EntityManager({
    serviceName: serviceName
});
var store = manager.metadataStore;
store.registerEntityTypeCtor('WO_Rout', assets);

When I query my controller this particular property "AssetJobEqNo" is sent and seen in the JSON raw results on the client side.

So....here is the weird part I can't figure out. If I run a query tied to a button on my UI the property IS loaded and in the object I assigned it, BUT it's still the default value of an empty string, it never loads. Then I run the EXACT same query again grabbing the same entities and this time the value IS there.

In conclusion, I'm confused as to why this extended entity's property is not being filled the first query but if I run the exact same query it loads the second time?

Hope this all makes sense.

dataService function:

function getWorkOrder(reqNo) {
    if (reqNo > 0) {
        var query = breeze.EntityQuery.from("GetWorkOrders");
        query = query.where("req_no", "==", reqNo)
            .expand(["WO_RtHelp.WO_Rout", "WO_RtHelp.WO_Rout.eqptmast", "WO_RtHelp.WO_Act.WO_Resources.persmast", "WO_RtHelp.WO_Act.WO_Resources.Kits", "WO_RtHelp.WO_Act.Activity", "WO_RtHelp.WO_Act.WO_Resources.customer", "WO_RtHelp.WO_Act.WO_Resources.eqptmast", "WO_RtHelp.WO_Act.WO_Resources.invsite.invmast", "WO_RtHelp.WO_Act.WO_Resources.crew"])
        return manager.executeQuery(query);
    } else {
        return throwNotification('Please enter a Work Order number.');
    }
}

controller function for succeeded queries

function querySucceeded(data) {

    $scope.WorkOrder = {};

    if (data.results.length === 0) {
        sysErrorNotification('No Work Order with System #' + $scope.workOrderSearchNumber);
    }
    else {
        $scope.WorkOrder = data.results[0];
        $scope.myData = $scope.WorkOrder.WO_RtHelp;
        $('#bottomNav a[href="/WorkOrders/#woMain"]').tab('show');
        resetDataSources();
        $scope.$apply();
    }
}

I'm using Breeze, Angular, Q, and jQuery

Bedard answered 19/9, 2013 at 15:10 Comment(3)
I have not worked with breeze so this may be an ignorant question, but how does querySucceeded get called? do you have a watch or something? You said you can see the request happen and the data gets updated, but what triggers angular to do a scope apply (or your function that has an apply to fire)? from console, does this make it work? angular.element($("[ng-app]")).scope().$apply();Photocopier
Its called based on the function in the dataservice. In the function that calls the dataservice there is a .then(querySucceeded) and .fail(queryFailed) to route the results of the query. And no that doesn't make it work as I'm already calling the apply method from the scope in angular.Bedard
Here is where the query is called: $scope.getAllWorkOrders = function () { workOrderDataservice.getWorkOrder($scope.workOrderSearchNumber) .then(querySucceeded) .fail(queryFailed); };Bedard
B
1

So after a few days of hammering away I believe I have resolved the problem. After following the entity in it's creating and merging process, when materializing from a query, I found where my property was being overwritten by the "rawEntity" which has the default value from the extended entity property of "".

I'm using Breeze 1.4.2 and debugging with breeze.debug.js and found on line 14854 the function proto.initializeFrom is causing this problem.

Here is what I did to fix this problem:

 proto.initializeFrom = function (rawEntity) {
        // HACK:
        // copy unmapped properties from newly created client entity to the rawEntity.
        // This is so that we don't lose them when we update from the rawEntity to the target.
        // Something that will occur immediately after this method completes. 
        var that = this;
        this.entityType.unmappedProperties.forEach(function(prop) {
            var propName = prop.name;
            that[propName] = rawEntity[propName];  // CassidyK 
            //rawEntity[propName] = that[propName]; // Breeze 
        });

        if (!this._backingStore) {
            this._backingStore = { };
        }
    };

I'll keep this updated if I find any problems with the fix I implemented here.

Bedard answered 20/9, 2013 at 14:22 Comment(0)
C
0

Check out Ward's answer in the below question - it should give you guidance on unmapped properties.

UnMapped property on the Angular/Breeze SPA template

I don't see how it is working at all to be honest, unless I am missing something you have butchered the expand()

query = query.where("req_no", "==", reqNo)
        .expand(["WO_RtHelp.WO_Rout", "WO_RtHelp.WO_Rout.eqptmast", "WO_RtHelp.WO_Act.WO_Resources.persmast", "WO_RtHelp.WO_Act.WO_Resources.Kits", "WO_RtHelp.WO_Act.Activity", "WO_RtHelp.WO_Act.WO_Resources.customer", "WO_RtHelp.WO_Act.WO_Resources.eqptmast", "WO_RtHelp.WO_Act.WO_Resources.invsite.invmast", "WO_RtHelp.WO_Act.WO_Resources.crew"])

should be a string, with values separated inside of it -

 query = query.where("req_no", "==", reqNo)
        .expand("WO_RtHelp.WO_Rout", "WO_RtHelp.WO_Rout.eqptmast, WO_RtHelp.WO_Act.WO_Resources.persmast, WO_RtHelp.WO_Act.WO_Resources.Kits, WO_RtHelp.WO_Act.Activity, WO_RtHelp.WO_Act.WO_Resources.customer, WO_RtHelp.WO_Act.WO_Resources.eqptmast, WO_RtHelp.WO_Act.WO_Resources.invsite.invmast, WO_RtHelp.WO_Act.WO_Resources.crew")

Note that I did not pass an array of strings, I passed a string that separated the values with commas.

Centrifugate answered 19/9, 2013 at 17:20 Comment(4)
I removed the brackets, still doesn't make a difference, as that handles the expanding which wasn't an issue. Regarding looking at the StackOverflow post you linked, I have read through it about a dozen times. The problem was not answered in the post, rather Ward states "I need a repro of that!" Per Breeze documentation the flow of entity materialization is so: When Breeze materialize an object through query or entity import, the sequence is 1. constructor 2. initializer function 3. merge into cache Considering this flow, the variable is set to '', BUT when merging the data should fill.Bedard
Update: I actually switched back to the brackets, as I was correct in using them. With more than one relation or navigation property to expand on, is an array and needs to be so. Reference here: #14236227Bedard
That question is from January, refer to the official API documentation HERE -breezejs.com/sites/all/apidocs/classes/…Centrifugate
Note, both ways work for expand. 1. .expand("WO_RtHelp.WO_Rout, WO_RtHelp.WO_Rout.eqptmast") ||or|| .expand(["WO_RtHelp.WO_Rout", "WO_RtHelp.WO_Rout.eqptmast"])Bedard

© 2022 - 2024 — McMap. All rights reserved.