1
votes

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

2
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();sasonic
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.CassidyK
Here is where the query is called: $scope.getAllWorkOrders = function () { workOrderDataservice.getWorkOrder($scope.workOrderSearchNumber) .then(querySucceeded) .fail(queryFailed); };CassidyK

2 Answers

1
votes

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.

0
votes

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.