Breeze URL generation for REST API and navigation properties - breeze

Ive been trying to use breeze with third party RESTful API - the API expects parameters of two types - deep linking like - localhost/request/5 for single entities (ie. request with id = 5) and parametrised queries using JSON encoded in URL (transformed by breeze with no problem).
The main problem is to make breeze to create request with URL such as:
localhost/request/{id}
not JSON encoded GET, while using breeze query "withParameters( {workorderid: id})"
And the second part of problem is using syntax like:
var query = breeze.EntityQuery
.from('request')
.withParameters(parameters)
.expand('requestDetails');
To query for two entities - main - request - and secondary - requestDetails (with deffered on access querying for value of the secondary object).
The result should be like on this image:
http://postimg.org/image/prurk75ol/
My model is defined by hand with two entities:
metadataStore.addEntityType({
shortName: "request",
namespace: "servicedesk",
dataProperties: {
workorderid: {
dataType: DT.Identity,
isPartOfKey: true
},
ignorerequest: {
dataType: DT.Boolean
}
},
navigationProperties: {
requestDetails: {
entityTypeName: "requestDetails:#servicedesk",
isScalar: true,
associationName: "request_requestDetails",
foreignKeyNames: ["workorderid"]
}
}
});
metadataStore.addEntityType({
shortName: "requestDetails",
namespace: "servicedesk",
dataProperties: {
workorderid: {
dataType: DT.Identity,
isPartOfKey: true
},
group: {
dataType: DT.String
},
description: {
dataType: DT.String
}
},
navigationProperties: {
request: {
entityTypeName: "request:#servicedesk",
isScalar: true,
associationName: "requestDetails_request",
foreignKeyNames: ["workorderid"]
}
}
Ive found example of this: https://github.com/Breeze/breeze.js.labs/blob/master/breeze.ajaxrestinterceptor.js , it looks like i can change url generation by intercepting ajax calls, can this be done for angular.breeze adapter?

I don't fully understand your question. What query are you having trouble with? Please edit your answer so we can help.
BUT I do see what looks like a metadata problem with your definition of the request type's requestDetails navigation property. Both the property name and the semantics suggest this should return a collection but you've defined it as a scalar.
requestDetails: {
entityTypeName: "requestDetails:#servicedesk",
isScalar: true, // <-- HUH?
associationName: "request_requestDetails",
foreignKeyNames: ["workorderid"]
}
I think you want isScalar: false,

Related

youtube api v3 CORS support in sencha touch 2

Using Sencha Touch, How do we query youtube v3 search api?
Below is the sample url which works fine when issued from a browser directly (NOTE: Key is required) :
"https://www.googleapis.com/youtube/v3/search?part=snippet&order=date&type=video&channelId=UC3djj8jS0370cu_ghKs_Ong&key=MY_KEY"
However the same url fails when loaded using sencha touch Store ajax proxy.
It seems that OPTIONS call is made against this URL and GET was aborted.
What is needed in Sencha touch store for working with youtube V3 google apis? I did not find jsonp support for youtube V3 api.
I have used this api like this,
proxy: {
type: 'ajax',
url: 'https://www.googleapis.com/youtube/v3/search',
useDefaultXhrHeader: false,
extraParams: {
part: 'snippet',
q: 'ambarsariya',
regionCode: 'IN',
maxResults: 30,
key: 'your_key'
},
reader: {
type: 'json',
rootProperty: 'items'
}
}
One more thing you have to do and thats is you have set a idProperty in the model of this store. Inside config of the model used I have used
idProperty: 'videoId',// its better if this name is not same as any fields name
fields: [{
name: 'snippet'
}, {
name: 'thumbnail',
mapping: 'snippet.thumbnails.default.url'
}, {
name: 'title',
mapping: 'snippet.title'
}]
Hope this solves your problem.
It works well for me.
STORE:-
Ext.define('MyApp.store.videos', {
extend: 'Ext.data.Store',
model: 'MyApp.model.Video',
config: {
autoLoad: true,
proxy: {
type: 'ajax',
//This is required to enable cross-domain request
useDefaultXhrHeader: false,
url: 'https://www.googleapis.com/youtube/v3/search',
extraParams: {
part: 'snippet',
q: "Enrique", //Query string
regionCode: 'IN',
maxResults: 30,
key: 'AIzaSyD6FvoLaIFqyQGoEY4oV7TEWGAJSlDd1-8'
}
}
}
});
This is the model used by the above store.
MyApp.model.Video:-
Ext.define('MyApp.model.Video', {
extend: 'Ext.data.Model',
requires: [],
config: {
idProperty: 'videoId',
fields: [{
name: 'id'
}, {
name: 'videoId',
mapping: 'id.videoId'
}]
}
});
It also works well for jsonp proxy also,
just change type: jsonp inside proxy and remove useDefaultXhrHeader config.

Error loading entities with a navigation property using custom metadata

I have the following implementation of a custom metadata scenario using the boiler plate with breeze.metadata-helper 1.0.7 and BreezeJS 1.4.16:
function addFoo() {
addType({
shortName: 'Foo',
dataProperties: {
Id: { type: ID },
BarId: { type: ID }
},
navigationProperties: {
Bar: {
entityTypeName: 'Bar',
associationName: 'Foo_Bar',
foreignKeyNames: ['BarId']
}
}
});
}
function addBar() {
addType({
shortName: 'Bar',
dataProperties: {
Id: { type: ID },
}
});
}
Upon completion of query (provided below) execution i receive the following error: TypeError: newValue.getProperty is not a function.
var query = breeze.EntityQuery.from('Foos').expand('Bar');
manager.execute(query).catch(function(error) { });
HTTP response contains the following JSON:
[{"Id":1,"BarId":2,"Bar":{"Id":2}}]
Though this query works fine if i replace foreignKeyNames: ['BarId'] with invForeignKeyNames: ['Id']. And still, in the latter case the navigation property Bar() of foo entity is not of entity type Bar but a simple javascript object.
The questions are:
1) Why the query with foreignKeyNames fails
2) Why foo.Bar() is not an entity of type Bar
Thanks.
I think the issue is with how you are serializing the result of your query. Take a look at the JsonResultsAdapter documentation where it discusses how to handle references in the json payload. You may need a custom JsonResultsAdapter ( pretty easy to write once you understand the idea).

Geo sorting and distance calculation in ElasticSearch not working

UPDATE I've also updated the mapping to include pin as the examples seem to suggest. Also, here's an temporary instance with some data to work with: https://21991e47cdc7caa8000.qbox.io/profiles/lead/_search
I've followed the instructions by ElasticSearch. Using this request:
$.ajax({
url: 'https://21991e47cdc7caa8000.qbox.io/profiles/lead/_search',
method: 'GET',
data: {
sort: [{
_geo_distance: {
"pin.location": [49.8998, -97.1375],
order: "asc",
unit: "km"
}
}]
},
success: function(response) {
console.log(response);
}
});
Does not return with calcuated distance or sorted by distance. I've also tried using "location".
Here's my mapping: https://21991e47cdc7caa8000.qbox.io/profiles/lead/_mapping
Any ideas?
I've managed to get it working, Please see the difference,
I converted data as json before quering, and added some configuration( changed dataType to json, and request type to POST, as we know GET request generally don't have body, only POST request does.
var request = {
sort: [{
_geo_distance: {
"pin.location": [
49.8998, -97.1375],
order: "asc",
unit: "km"
}
}]
};
$.ajax({
url: 'https://21991e47cdc7caa8000.qbox.io/profiles/lead/_search',
type: 'POST',
crossDomain: true,
dataType: 'json',
data: JSON.stringify(request),
success: function (response) {
console.log(JSON.stringify(response));
}
});
Hope this helps.
I've tested, and it should work for you too.
The example given uses pin.location, not location or lead.location.
Additionally, pin.location is an array of length 2, not an object with two fields as you are using it. This seems pretty counter-intuitive to me, as the location field in most other api calls is an object like you are using.
Try this:
$.ajax({
url: "https://myhostedes.com/profiles/lead/_search",
method: "GET",
data: {
"sort": [{
"_geo_distance": {
"pin.location": [49.8998, -97.1375],
"order": "asc",
"unit": "km"
}
}]
},
success: function(response) {
console.log(response);
}
});
Note: I don't have access to an elastisearch instance at the moment, so I haven't been able to run this yet.

Breeze How to write entity related queries against local cache

I am trying to figure out how to write a query that will filter my related entities using the executeQueryLocally.
Here is my example:
var queryStageConfigs = breeze.EntityQuery
.from("Stages")
.where("StageConfig.ConfigValue", '==', 'Green')
.expand("StageConfig");
var stageConfigs = self.manager.executeQueryLocally(queryStageConfigs);
This the error I am getting back:
Error: unable to locate property: ConfigValue on entityType: Stages:#
MetadataStore
//Stages Entity
metadataStore.addEntityType({
shortName: "Stages",
//namespace: "MonitoringCenter",
dataProperties: {
id: { dataType: DT.Int64, isPartOfKey: true },
institutionId: { dataType: DT.Int64 },
qualifiedName: { dataType: DT.String },
displayName: { dataType: DT.String },
displayOrder: { dataType: DT.Int64 },
},
navigationProperties: {
institution: {
entityTypeName: "Stages",
isScalar: true,
associationName: "Institution_Stages",
foreignKeyNames: ["institutionId"]
},
stageConfig: {
entityTypeName: "StageConfig",
isScalar: false,
associationName: "Stages_StageConfig"
}
}
});
metadataStore.setEntityTypeForResourceName("Stages", "Stages");
//StageConfig Entity
metadataStore.addEntityType({
shortName: "StageConfig",
//namespace: "MonitoringCenter",
dataProperties: {
id: { dataType: DT.Int64, isPartOfKey: true },
stageId: { dataType: DT.Int64 },
configName: { dataType: DT.String },
configValue: { dataType: DT.String },
},
navigationProperties: {
stages: {
entityTypeName: "StageConfig",
isScalar: true,
associationName: "Stages_StageConfig",
foreignKeyNames: ["stageId"]
}
}
});
metadataStore.setEntityTypeForResourceName("StageConfig", "StageConfig");
I am hand writing the JsonResultsAdpater to get the JSON data into the entities that have created using the metadataStore setting up the relationship between the entities.
When I query the Stages entities I can see the StageConfigs array and it is not empty.
Any clue on what I may be doing wrong?
Any help would be greatly appreciated!
Ok, your example is a little confusing because I can't tell the cardinality of the relationships based on your names. In general, I think of a pluralized name like 'stages' as being a collection of 'Stage' entities (i.e. isScalar = false). But in your case the 'stages' property is actually scalar and its inverse, the 'stageConfig' property, a singularized name, is actually non-scalar. If this assumption is correct then the reason that your query will not work is because the stage.stageConfig property needs to be a scalar in order for your query to work, unless you want to use the 'any/all' operators. i.e. something like
var queryStageConfigs = breeze.EntityQuery
.from("Stages")
.where("StageConfig", "any", "ConfigValue", "==", 'Green');
.expand("StageConfig");
( and shouldn't the query be called 'queryStages' because you are querying and returning 'stages')
Also, just a nit, but its probably a good idea to keep all of your entityType names singular and your resource names plural. This is not a requirement, but it is certainly confusing the way you have one entityType singularized ( StageConfig) and another pluralized (Stages).
I don't see any mention in your code about using the camelCase naming convention, but the example seems to indicate that you are assuming that this is set.

Infragistics Jquery Tree

I need some help from you in using igTree when LoadOnDemand is set to true.
I have a WCF REST Service which is giving me data to populate in igTree.
Please find the sample code..
$.ajax(
{
type: "GET",
url: "AssessmentProcWCFService.svc/GetAllEntities",
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: '{}',
cache: false,
success: OnGetAllEntitiesSuccess,
error: OnGetAllEntitiesFailure
});
==================================================
function OnGetAllEntitiesSuccess(categoryList) {
$("#APTreeView").igTree({
animationDuration: 0,
dataSourceType: 'json',
dataSource: categoryList.d,
initialExpandDepth: false,
loadOnDemand: true,
dataSourceUrl: "AssessmentProcWCFService.svc/GetAllCategories?EntityID=primaryKey:id",
bindings: {
textKey: 'text',
valueKey: 'id',
primaryKey: 'id',
expanded: 'expanded',
childDataProperty: 'children'
}
});
}
=========================================================
Questions:-
How could I send the selected node ID to the Service when any node of the tree is expanding?
The way I am sending in the above example it is not working when I am retrieving it in the service “public List GetAllCategories()” like
“string entityID = HttpContext.Current.Request.QueryString["EntityID"];”
I am getting entity id as null.
How the tree get rendered when any node get expanded if LoadOnDemand is true?
Please help me on this I have spend lot of time in it.
Basically you can encode anything you like in the request made to the service:
Here are the default request parameters explained: http://www.infragistics.com/community/forums/t/65356.aspx
And here is how you can add a request parameter:
function OnGetAllEntitiesSuccess(categoryList) {
$("#APTreeView").igTree({
animationDuration: 0,
dataSourceType: 'json',
dataSource: categoryList.d,
initialExpandDepth: false,
loadOnDemand: true,
dataSourceUrl: "AssessmentProcWCFService.svc/GetAllCategories?EntityID=primaryKey:id",
bindings: {
textKey: 'text',
valueKey: 'id',
primaryKey: 'id',
expanded: 'expanded',
childDataProperty: 'children'
},
nodePopulating: function (event, ui) {
var node = '&SelectedNodeID=' + $("#APTreeView").igTree('selectedNode').element.attr('data-value'),
myNewUrl = 'AssessmentProcWCFService.svc/GetAllCategories?EntityID=primaryKey:id' + node;
$('#myTree').igTree('option', 'dataSourceUrl', myNewUrl);
}
});
}

Resources