Navigation property is null when using fetchEntityByKey method in breeze - breeze

How can I also fetch navigation property of an entity while using fetchEntityByKey method in breeze ? Is it even possible ?

If you want to "fetch" the value of a navigation property use the EntityAspect.loadNavigationPrperty method
myEntity.entityAspect.loadNavigationProperty("Orders").then(function (data) {
var orders = data.results;
}).fail(function (exception) {
// handle exception here;
});

Related

getProperty of entity in Odata model in SAPUI5 not working

I have a oData model with entities : Order, OrderInformation. There is 1 : 1 an association between Order and OrderInformation.
Now in the view, based on a value in OrderInformation, I should hide / display a button.
In the controller, following logic to get the value of OrderInformation->appUrl does not work but I can read the property of entity 'Order'.
Init: function(){
// Not working
var prop = this.getView().getModel().getProperty("/OrderInformations('"+ this._orderId + "')/appUrl");
// Working
var prop = this.getView().getModel().getProperty("/Orders('"+ this._orderId + "')/orderType");
}
In transaction /IWFND/GW_CLIENT, following query gives me correct value
/sap/opu/odata/sap/<<ServiceURL>>/OrderInformations('132123')/appUrl
I also tried with the attachRequestCompleted but still no success.
Init:function(){
var oModel = this.getView().getModel();
oModel.attachRequestCompleted(function(oEvent){
var myval = model.getProperty("/OrderInformations('"+ this._orderId + "')/appUrl");
});
}
Can someone provide any idea what can be going wrong ?
BR
Nilesh
You can use the oModel.read function to trigger a request to the backend, within the success handler you read the result of the response and process the received data
var test = oModel.read("OrderInformations('" + this._orderId + "')", {
success: function(oData, response) {
var appUrl = oData.result.appUrl; //response.data.appUrl also works
// do something
},
error: function (oError) {
// Error handling on failed response
}
});
API reference: https://openui5beta.hana.ondemand.com/#docs/api/symbols/sap.ui.model.odata.ODataModel.html#read
I don't understand this line you wrote:
In the controller, following logic to get the value of
OrderInformation->appUrl does not work but I can read the property of
entity 'Order'.
Order is another Entity with a property and the addressing for this works like described above?
Did you init your model like this:
/sap/opu/odata/sap/<<ServiceURL>>/Order? Is OrderInformation a related entity of Order? If yes extend the read with the Navigation property of the odata service which defines the relationship between the two Entities
I hope this answers you question, if anything left, let me know
Best regards

Breeze - How to Load Navigation property from cache

I am getting a single entity by using a method fetchEntityByKey, after that I am loading navigation property for the entity by entityAspect.loadNavigationProperty. But loadNavigationProperty always make a call to the server, what I am wondering if I can first check it from cache, if it is exist then get it from there otherwise go the server. How is it possible? Here is my current code
return datacontext.getProjectById(projectId)
.then(function (data) {
vm.project = data;
vm.project.entityAspect.loadNavigationProperty('messages');
});
Here is a function that I encapsulated inside datacontext service.
function getProjectById(projectId) {
return manager.fetchEntityByKey('Project', projectId)
.then(querySucceeded, _queryFailed);
function querySucceeded(data) {
return data.entity;
}
}
Also, how is it possible to load navigation property with some limit. I don't want to have all records for navigation property at once for performance reason.
You can use the EntityQuery.fromEntityNavigation method to construct a query based on an entity and a navigationProperty . From there you can execute the resulting query locally, via the EntityManager.executeQueryLocally method. So in your example once you have a 'project' entity you can do the following.
var messagesNavProp = project.entityType.getProperty("messages");
var query = EntityQuery.fromEntityNavigation(project, messagesNavProp);
var messages = myEntityManager.executeQueryLocally(query);
You can also make use of the the EntityQuery.using method to toggle a query between remote and local execution, like this:
query = query.using(FetchStrategy.FromLocalCache);
vs
query = query.using(FetchStrategy.FromServer);
please take a look here: http://www.breezejs.com/sites/all/apidocs/classes/EntityManager.html
as you can see fetchEntityByKey ( typeName keyValues checkLocalCacheFirst ) also have a third optional param that you can use to tell breeze to first check the manager cache for that entity
hope this helps

BreezeJS - Using expand

I am querying the server to get an entity with expand
function _loadIncidents() {
var deffered = Q.defer(),
queryObj = new breeze.EntityQuery().from('Incidents').expand(['Deployments', 'IncidentComments', 'DTasks', 'ExtendedProperties', 'IncidentEvents']);
dataRepository.fetchEntitiesByQuery(queryObj, true).then(function (incidents) {
var query = breeze.EntityQuery.from("DTasks"),
incidentIds = dataRepository.getEntitiesByQuerySync(query);
deffered.resolve();
}, function(err) {
deffered.reject(err);
});
return deffered.promise;
};
I am getting the results and all is fine, how ever when I query breeze cache to get the entities - I am getting empty collection. So when using expand does the expanded entities are added to the cache?
Yes the related entities identified in the expand should be in cache ... if the query is "correct" and the server interpreted your request as you intended.
Look at the payload of the response from the first request. Are the related entities present? If not, perhaps the query was not well received on the server. As a general rule, you want to make sure the data are coming over the wire before wondering whether Breeze is doing the right thing with those data.
I do find myself wondering about the spelling of the items in your expand list. They are all in PascalCase. Are they these the names of navigation properties of the Incident type? Or are they the names of the related EntityTypes? They need to be former (nav property names), not the latter.
I Had problem with the navigation property - as I am not using OData webapi not using EF , there is problem with the navigation properties so for the current time i just wrote
Object.defineProperty(this, 'Deployments', {
get: function () {
return (this.entityAspect && this.entityAspect.entityManager) ?
this.entityAspect.entityManager.executeQueryLocally(new breeze.EntityQuery("Deployments").
where('IncidentID', 'eq', this.IncidentID)) :
[];
},
set: function (value) { //used only when loading incidents from the server
if (!value.results) {
return;
}
var i = 0,
dataRepository = require('sharedServices/dataRepository');
for (i; i < value.results.length; i++) {
dataRepository.addUnchangedEntity('Deployment', value.results[i]);
}
},
enumerable: true
});

Is it possible that MVC is caching my data some place?

I have the following controller action:
public ActionResult Details(string pk)
{
IEnumerable<ContentDetail> model = null;
try
{
model = _content.Details(pk);
if (model.Count() > 0)
{
return PartialView(getView(pk) + "Details", model);
}
}
catch (Exception e)
{
log(e);
}
return Content("No records found");
}
I call this with the following routine:
$.ajax({
cache: false,
url: "/Administration/" + table + "s/Details",
data: { pk: partitionKey },
dataType: 'html',
success: function (responseText) {
$('#detailData').html(responseText);
$(".updatable")
.change(function (e) {
var type = $(this).attr('id').split('_')[0];
updateField(table, $(this), type);
});
$('.dialogLink')
.click(function () {
dialogClick(this);
return false;
});
},
error: function (ajaxContext) {
ajaxOnFailure(ajaxContext)
}
});
What I notice is that sometimes when I put a break point on the first line of the controller action then it does not seem to stop at the breakpoint. Is it possible the results are being cached by MVC and how could I stop this from happening while I debug?
Check for any variation of OutputCache being set on the controller itself or, if present, a base controller all your controllers may inherit from.
I've also noticed IE likes to cache things and found the only way to alleviate this is doing to the developer window and clearing the cache (or ctrl+shift+del)
Try adding cache:false to your .ajax call and see if that has any bearing (jQuery will append a timestamp variable making each call unique). Nevermind, just noticed you have it included. Must be getting late here--sure sign it's bed time when I miss things like this.
Load up fiddler and see if the request is even coming back from the browser. Ideally you'll want I write out no cache headers through one of the many methods mentioned here
Disable browser cache for entire ASP.NET website

MVC ActionMethod not finding passed in Value

I have a Create ActionMethod, something along the lines of:
[AcceptVerbs(HttpVerbs.Post)]
public ActionMethod Create(Journey journey)
{
if (Request.IsAjaxRequest())
{
//Save values
return Json(new { JourneyID = journey.JourneyID } );
}
}
The Journey object that I pass in is from my LINQ2SQL datamodel. I call the above ActionMethod from my Javascript using the JQuery.Post function, like:
var journeyData = {
CustomerID: $('#CustomerID').val(),
JourneyID: $('#JourneyID').val(),
EstimatedTravelTime: $('#EstimatedTravelTime').val(),
RouteName: $('#RouteName').val(),
.....
};
$.post('/Journey/Create',
journeyData,
function(jsonResult) {
//deal with result
},
'json'
);
The issue that I am having is that in the ActionMethod Journey.RouteName is always returning as null but the JSON that I pass back has a value, I check this using
alert(JSON.stringify(journeyData));
and in the resultant JSON object RouteName has a value, e.g. 'Go to work'. Any ideas why this wouldn't be being set in the ActionMethod? All other values that I pass back are being set fine.
Just a try and error suggestion:
First thing i would try is to rename "RouteName" param with somethign different, as "RouteName" is also a property of some MVC-redirect methods..
Have you examined your request JSON object that's going to the server?
Have you tried adding quotes to your string property value?
Like this:
var journeyData = {
CustomerID: $('#CustomerID').val(),
JourneyID: $('#JourneyID').val(),
EstimatedTravelTime: $('#EstimatedTravelTime').val(),
RouteName: '"' + $('#RouteName').val() + '"',
.....
};
There are a couple of things to consider. I'm guessing this is already in place, but your model must have a getter and setter on the RouteName property in order to be properly bound. Another thought is you might not be establishing the strong binding. This is usually done as part of the view's page declaration (e.g. Inherits="System.Web.Mvc.ViewPage") but I'm not sure this is happening prior to your post.

Resources