Following the tutorial, there is the query
query selectCommoditiesByOwner {
description: "Select all commodities based on their owner"
statement:
SELECT org.acme.biznet.Commodity
WHERE (owner == _$owner)
}
But nowhere is an example explaining how to request it
For the parameter owner, I tryed with the node variable owner
owner.toUri()
owner.getFullyQualifiedIdentifier()
"resource:" + owner.getFullyQualifiedIdentifier()
But nothing works
Does somebody has a working example?
Example on how to 'request it' is shown in the REST API section of the Queries tutorial https://hyperledger.github.io/composer/tutorials/queries
If you mean: request it from within a Transaction Processor function, using the APIs - there is an example in the same tutorial, of calling a Query function eg.
/**
* Remove all high volume commodities
* #param {org.acme.biznet.RemoveHighQuantityCommodities} remove - the remove to be processed
* #transaction
*/
function removeHighQuantityCommodities(remove) {
return getAssetRegistry('org.acme.biznet.Commodity')
.then(function (assetRegistry) {
return query('selectCommoditiesWithHighQuantity')
.then(function (results) {
// process results objects etc
so using your query - you might do something like:
var tx_owner = tx.owner; // passed into the Transaction Processor for example
return query('selectCommoditiesByOwner', {
"owner": tx_owner // eg "resource:org.acme.trading.Trader#trader1"
})
.then(function (results) {
// do something
hope this helps. See further reference here -> https://hyperledger.github.io/composer//reference/query-language
Related
This issue is migrated from a question on our Github account because we want the answer to be available to others. Here is the original question:
Hello,
Following is the InstanceQuery I tried
http://localhost:3000/3_0_1/Questionnaire/jamana/$graphql?query={id}
I am receiving back response as Cannot query field \"id\" on type \"Questionnaire_Query\"
So what is the right format I should try ?
https://build.fhir.org/graphql.html has a sample as http://test.fhir.org/r3/Patient/example/$graphql?query={name{text,given,family}}.Its working in their server. I cannot get the response When I try similarly in our graphql-fhir.
Original answer from Github:
We are using named queries since we are using express-graphql. I do not believe that is valid syntax. Also, the url provided does not seem to work, I just get an OperationOutcome saying the patient does not exist, which is not a valid GraphQL response.
Can you try changing your query from:
http://localhost:3000/3_0_1/Questionnaire/jamana/$graphql?query={id}
to this:
http://localhost:3000/3_0_1/Questionnaire/jamana/$graphql?query={Questionnaire{id}}
When writing the query, you need to provide the return type as part of the instance query. You should get a response that looks like similar to this(if you have implemented your resolver you will have data and not null):
{
"data": {
"Questionnaire": {
"id": null
}
}
}
and from a later comment:
If you are getting null then you are doing it correctly, but you haven't wrote a query or connected it to a data source. You still need to return the questionnaire in the resolver.
Where you are seeing this:
instance: {
name: 'Questionnaire',
path: '/3_0_1/Questionnaire/:id',
query: QuestionnaireInstanceQuery,
},
You are seeing the endpoint being registered with an id parameter, which is different from a GraphQL argument. This is just an express argument. If you navigate to the questionnaire/query.js file, you can see that the QuestionnaireInstanceQuery query has a different resolver than the standard QuestionnaireQuery. So in your questionnaire/resolver.js file, if you want both query and instance query to work, you need to implement both resolvers.
e.g.
// This is for the standard query
module.exports.getQuestionnaire = function getQuestionnaire(
root,
args,
context = {},
info,
) {
let { server, version, req, res } = context;
// Do query and return questionnaire
return {};
};
// This one is for a questionnaire instance
module.exports.getQuestionnaireInstance = function getQuestionnaireInstance(
root,
args,
context = {},
info,
) {
let { server, version, req, res } = context;
// req.params.id is your questionnaire id, use that for your query here
// queryQuestionnaireById does not exist, it is pseudo code
// you need to query your database here with the id
let questionnaire = queryQuestionnaireById(req.params.id);
// return the correct questionnaire here, default returns {},
// which is why you see null, because no data is returned
return questionnaire;
};
I am not able to display records on my report.
Report Source: Group Approval(sysapproval_group) table
Condition:Sys Id - is one of - javascript: new GetMyGroupApprovals().getSysIds();
Script Include : MyGroupApproval
Note : Active is checked, Accesible is all application score & Client callable unchecked
var GetMyGroupApprovals = Class.create();
GetMyGroupApprovals.prototype = {
initialize: function() {
},
getSysIds : function getMyGroupMembers(){
var ga = new GlideRecord('sysapproval_group');
ga.addQuery('parent.sys_class_name', '=', 'change_request');
ga.query();
gs.log("TotalRecords1 Before:: " + ga.getRowCount());
var sysIdArray = [];
while(ga.next()){
sysIdArray.push(ga.sys_id);
}
return sysIdArray;
},
type: 'GetMyGroupApprovals'
};
Kindly note that I have to achieve with script approach. I am not able to get records on my report.
This line is probably causing unexpected behavior:
sysIdArray.push(ga.sys_id);
ga.sys_id returns a GlideElement object, which changes for each of the iterations in the GlideRecord, so the contents of sysIdArray will just be an instance of the same object for each row in the result set, but the value will just be the last row in the set.
You need to make sure you push a string to the array by using one of the following methods:
sysIdArray.push(ga.sys_id+''); // implicitly call toString
sysIdArray.push(ga.getValue('sys_id')); // return string value
Quick suggestion, you can use the following to get sys_ids as well:
sysIdArray.push(ga.getUniqueValue());
I am trying to load an entity based on a Query and allow the user to edit it. The entity loads without issues from the query, however it does not load its related entities, leaving detail pickers unfilled when loading the edit screen.
This is the code that I have:
myapp.BrowseCOAMissingHoldingCompanies.VW_ChartOfAccountsWithMissingHoldingCompanies_ItemTap_execute = function (screen) {
var accountName = screen.VW_ChartOfAccountsWithMissingHoldingCompanies.selectedItem.AccountFullName;
return myapp.activeDataWorkspace.Accounting360Data.FindChartOfAccountsMappingByAccountName(accountName)
.execute().then(function (query) {
var coa = query.results[0];
return myapp.showAddEditChartOfAccountsMapping(coa, {
beforeShown: function (addEditScreen) {
addEditScreen.ChartOfAccountsMapping = coa;
},
afterClosed: function () {
screen.VW_ChartOfAccountsWithMissingHoldingCompanies.refresh();
}
});
});
};
Interestingly if I open the browse screen (and nothing else) of that entity type first (which does retrieve the entity), then the related entities load correctly and everything works, but I can't figure out how to make that level of load happen in this code.
One method of tackling this (and to avoid the extra query execution of a follow on refresh) is to use the expand method to include any additional navigation properties as follows:
myapp.BrowseCOAMissingHoldingCompanies.VW_ChartOfAccountsWithMissingHoldingCompanies_ItemTap_execute = function (screen) {
var accountName = screen.VW_ChartOfAccountsWithMissingHoldingCompanies.selectedItem.AccountFullName;
return myapp.activeDataWorkspace.Accounting360Data.FindChartOfAccountsMappingByAccountName(
accountName
).expand(
"RelatedEntity," +
"AnotherRelatedEntity," +
"AnotherRelatedEntity/SubEntity"
).execute().then(function (query) {
var coa = query.results[0];
return myapp.showAddEditChartOfAccountsMapping(coa, {
beforeShown: function (addEditScreen) {
addEditScreen.ChartOfAccountsMapping = coa;
},
afterClosed: function () {
screen.VW_ChartOfAccountsWithMissingHoldingCompanies.refresh();
}
});
});
}
As you've not mentioned the name of your entity's navigational properties, I've used coa.RelatedEntity, coa.AnotherRelatedEntity and coa.AnotherRelatedEntity.SubEntity in the above example.
As covered by LightSwitch's intellisense (in msls-?.?.?-vsdoc.js) this method 'Expands results by including additional navigation properties using an expression defined by the OData $expand system query option' and it accepts a single parameter of 'An OData expand expression (a comma-separated list of names of navigation properties)'.
The reason your forced refresh of coa also populates the navigational properties is that LightSwitch's refresh method implicitly expands all navigation properties (provided you don't specify the navigationPropertyNames parameter when calling the refresh). The following shows the internal implementation of the LightSwitch refresh method (with the implicit expand behaviour executing if the navigationPropertyNames parameter is null):
function refresh(navigationPropertyNames) {
var details = this,
properties = details.properties.all(),
i, l = properties.length,
property,
propertyEntry,
query;
if (details.entityState !== _EntityState.unchanged) {
return WinJS.Promise.as();
}
if (!navigationPropertyNames) {
navigationPropertyNames = [];
for (i = 0; i < l; i++) {
property = properties[i];
propertyEntry = property._entry;
if (isReferenceNavigationProperty(propertyEntry) &&
!isVirtualNavigationProperty(propertyEntry)) {
navigationPropertyNames.push(propertyEntry.serviceName);
}
}
}
query = new _DataServiceQuery(
{
_entitySet: details.entitySet
},
details._.__metadata.uri);
if (navigationPropertyNames.length > 0) {
query = query.expand(navigationPropertyNames.join(","));
}
return query.merge(msls.MergeOption.unchangedOnly).execute();
}
However, if you take the refresh approach, you'll be performing an additional unnecessary query operation.
Entity Framework uses lazy loading by default, so related data will be loaded on demand, but in your case that's too late because the entity is already client-side a that point.
Try using the Include method in your query if you want eager loading.
Calling refresh on the details of the entity seems to do it:
return coa.details.refresh().then(function() {
return myapp.showAddEditChartOfAccountsMapping(coa, {
beforeShown: function (addEditScreen) {
addEditScreen.ChartOfAccountsMapping = coa;
},
afterClosed: function () {
screen.VW_ChartOfAccountsWithMissingHoldingCompanies.refresh();
}
});
});
You should use load method to fetch related data from Server. At this time we don't have any ways to force msls load related data.
r.db('dbname').table('urls').filter(function(url) {
return url("expires_at").date().eq(r.now().date())
.and(url("expires_at").hours().eq(r.now().hours().sub(1)))
});
I am trying to write the equivalent query using thinky ORM for node.js
I've never worked with Thinky, but according to docs, you should create model and make query on it.
1) Create model. I don't know what documents you are storing in Rethink. But something like this:
var thinky = require('thinky')();
var type = thinky.type;
// Create a model
var Urls = thinky.createModel("urls", {
id: String,
expires_at: Date
// another fields if needed
});
2) Query:
Don't know actual syntaxes for filter in Thinky, but somehting like this:
Urls.filter(function(url) {
return url("expires_at").date().eq(r.now().date())
.and(url("expires_at").hours().eq(r.now().hours().sub(1)))
}).then(function(result) {
// result is an array of instances of `Urls `
});
I am working with Angular Meteor and am having an issue with my objects/arrays. I have this code:
angular.module("learn").controller("CurriculumDetailController", ['$scope', '$stateParams', '$meteor',
function($scope, $stateParams, $meteor){
$scope.curriculum = $meteor.object(CurriculumList, $stateParams.curriculumId);
$scope.resources = _.map($scope.curriculum.resources, function(obj) {
return ResourceList.findOne({_id:obj._id})
});
console.log($scope.resources)
}]);
I am attempting to iterate over 'resources', which is a nested array in the curriculum object, look up each value in the 'ResourceList' collection, and return the new array in the scope.
Problem is, sometimes it works, sometimes it doesnt. When I load up the page and access it through a UI-router link. I get the array as expected. But if the page is refreshed, $scope.resources is an empty array.
My thought is there is something going on with asynchronous calls but have not been able for find a solution. I still have the autopublish package installed. Any help would be appreciated.
What you're going to do is return a cursor containing all the information you want, then you can work with $meteor.object on the client side if you like. Normally, publishComposite would look something like this: (I don't know what your curriculum.resources looks like)
Use this method if the curriculum.resources has only ONE id:
// this takes the place of the publish method
Meteor.publishComposite('curriculum', function(id) {
return {
find: function() {
// Here you are getting the CurriculumList based on the id, or whatever you want
return CurriculumList.find({_id: id});
},
children: [
{
find: function(curr) {
// (curr) will be each of the CurriculumList's found from the parent query
// Normally you would do something like this:
return ResourceList.find(_id: curr.resources[0]._id);
}
}
]
}
})
This method if you have multiple resources:
However, since it looks like your curriculum is going to have a resources list with one or many objects with id's then we need to build the query before returning anything. Try something like:
// well use a function so we can send in an _id
Meteor.publishComposite('curriculum', function(id){
// we'll build our query before returning it.
var query = {
find: function() {
return CurriculumList.find({_id: id});
}
};
// now we'll fetch the curriculum so we can access the resources list
var curr = CurriculumList.find({_id: id}).fetch();
// this will pluck the ids from the resources and place them into an array
var rList = _.pluck(curr.resources, '_id');
// here we'll iterate over the resource ids and place a "find" object into the query.children array.
query.children = [];
_.each(rList, function(id) {
var childObj = {
find: function() {
return ResourceList.find({_id: id});
}
};
query.children.push(childObj)
})
return query;
});
So what should happen here (I didn't test) is with one publish function you will be getting the Curriculum you want, plus all of it's resourceslist children.
Now you will have access to these on the client side.
$scope.curriculum = $meteor.object(CurriculumList, $stateParams.curriculumId);
// collection if more than one, object if only one.
$scope.resources = $meteor.collection(ResoursesList, false);
This was thrown together somewhat quickly so I apologize if it doesn't work straight off, any trouble I'll help you fix.