I have a problem where I need to select a specific value from a specific entity from a entity set, however, I need to do it in a way without knowing the key.
This is the query I actually need:
odata/..../picklistLabels(locale='en_GB',optionId=10819)/label
However I need to program it in a way so it automatically selects the label without knowing the optionId. Is there a way to do this in OData?
From your question, I think that you want to perform a navigation but you don't have a key. Unfortunately, this exact functionality isn't available, however, you can perform an expand like this:
odata/..../picklistLabels?$filter=locale eq 'en_GB' and optionId=10819&$expand=label
This will get you the same information that the other call would do but in a slightly different format, you would have to find the first element in the array and then get the label property to get that information
As an aside, if you have the option to change the server (I'm guessing not due to the sapui5 tag but it might be useful for other users) you could change the key. If the locale and the optionId are enough to identify the object, then you could make these into a composite key. Here is a link for an example within the WebAPI OData source code: https://github.com/OData/ODataSamples/tree/master/WebApi/v4/ODataCompositeKeySample
Related
I am currently trying to make an Odata call where I filter by a "multi-level" expanded property, however, none of the documentation or information I can find on this covers exactly what I am trying to accomplish. Does anyone know if this can be done, and how?
This is for letting our users be able to filter their Tests by the name of the Room the test was taken in. We have been able to filter by a single level of expanding, letting users filter their Tests by the name of the location, but we just can't seem to get the syntax right with the second level.
For context, our Test table is linked to a location table that is linked to a room table.
We are able to see the expanded information without a filter by calling:
.../api/Tests$expand=Location($select=Id,LocationName;$expand=Room($select=Id,RoomName))
returns:
...{"Id":19955,"LocationId":102,"Location":{"Id":102,"LocationName":"TestLocation","Room":{"Id":8,"RoomName":"TestRoom"}},...
But when we try a filtered call such as:
.../api/Tests$expand=Location($select=Id,LocationName;$expand=Room($select=Id,RoomName))&$filter=contains(Location/Room/RoomName,%27a%27))
All we get is the standard:
{"error":{"code":"NotFound","message":"The type 'Edm.String' is not an entity type. Only entity types support $select and $expand.\r\nParameter name: context"}}
There is surely some way of being able to filter from a multi-levelled expand, but I am somewhat of a newbie to Using OData, so any help would be appreciated!
Also, I believe we are using OData - 7.01.
Just answering my own question here, as it turns out the way we were doing it was correct.
The system was breaking in other areas down the pipe.
I would like to remove features from layers when using Openlayers3. I know that we can feature.setId(id) when create features and get with feature.getId() to remove them. But if the features is loading from the database or geoserver, they don't have a proper 'ID' Property.
So is a way to remove the selected features without setting feature id?
You have to make your question more clear.
Do you want to delete the features from the DB or you just want to remove them from the client and take no further action on the DB?????
If you dont have an id I guess there should be something identical amoung the feature attributes. I mean if you executed an sql delete script wouldnt you use an identifier to delete them????
So I pressume your features have a primary key or something identical to distinguish them.
So lets assume your fetaures have an identical column named "MYPK". If so you can iterate throught features and grap this identical attribute
var pksToDelete = new Array();
for (var i=0;i<features.length;i++){
pksToDelete.push(features[i].get('MYPK'));
}
now you have all the unique ids of your features into an array.
If you want to delete them from DB go for a wfs-t request using these ids and then do a refresh to your layer.
Better provide a sample code you use and explain in detail your purpose so I can help you in detail.
I know that Angular2 has #ViewQuery to get a QueryList of components matching the given type. But is there a way to get a reference to a particular component in this QueryList?
Right now, the only way I can think to do this is to give the component an extra "id" field, then iterate through the QueryList and check if the identifier is the one I want, e.g.:
getComponentById(QueryList<HasIdField> queryList, String id) =>
queryList.singleWhere((component) => component.id == id);
But this seems like a common enough problem that it seems like there should be a way to do this without adding this "id" boilerplate. I know that a component can be referenced locally within a template using #, but is there a way to reference a component similarly within a class?
Currently this functionality does not exist, see here for details on why the functionality to implement a custom filter is currently on hold due to potential performance reasons.
So the way you are doing it seems to be the right way given the functionality that is available currently, but this might change as the framework is now in alpha.
I understand that in MVC pattern and in REST services it is common to use URIs like /items/{id} but what is bad thing about using query parameters in the URI?
GET /items/{id} vs GET /items?id={id}
Further, lets say an entity has 'referenceId' field that points to some related (say parent) entity, and I need to create REST service to get all items for parent entity, which way is better:
GET(POST) /items/parent/{parentId}
or
GET(POST) /items?parent={parentId}
Will be grateful for insights that would help to resolve my subjective issues on constructing URLs for REST services.
I would use the following schemes.
/items/id
This uniquely addresses a resource of items with id id. We are not using parameters as a parameter to uniquely address this resource (as is the case with the other option). Just as
miguelcobain suggests.
/parent/id/items
Here id is an id to uniquely address a resource of parent and from those we collect/retrieve the items it references. From what you have said in the question it seems that parent references multiple items, like a container or collection.
The convention I use for this is to narrow down the scope going from left to right. Therefore in case items could be active or inactive. Thusly items have a property or attribute to be active or inactive. Narrowing down on this I get the following scheme:
/items/active
/parent/id/active
For your first question:
/items/{id} should retrieve a single resource with the specified id or 404 if it doesn't exist.
/items/?id={id} should retrieve an array (even if only one in the array) because you are querying the collection.
For your second question:
I agree with #miguelcobain's assessment - if the item is a specific resource/entity, just use the proper resource path to retrieve it.
To make this easier on the consumer, create a link header with rel="parent" and/or include the uri in the child resource. For an example of link headers, see GitHub's pagination api.
Of course, REST principles don't care about aesthetic details on URLs. It just imposes that every resource should be uniquely addressable.
Furthermore, using the query parameters to uniquely address something "kind of" violates the semantics of a "parameter", doesn't it? A parameter should be something optional, something additional and parameterized. Something like a detailed search on a collection of items, for example.
What you wrote may make sense in some cases. It depends.
In your example, is the item really a resource? If not, you could just do GET(POST) /parents/{parentId}.
If parent is, say, a boolean, and you want to search the items that have parent equals to true, then using the parameters makes sense. But since you're explicitly saying that you want a parent with a specific id, I assume that parent is a resource itself and I would uniquely address that resource using your option 1.
I hope I made myself clear.
It seems to me there are no rules to follow.
items/{id} - this convention is suitable for GET item by given id. If user doesn't provide id then it returns 404 status code.
items/id={id}&name={name} - this type of convention is suitable for search multiple items by given criteria. If no items are found, it is not a 404 situation, you simply say "I successfully found nothing matching your search criteria"
I have a customer requirement to export the checks written in QuickBooks into a specific format because their bank allows fraud prevention by uploading a file and they verify the name on the check against what you give them before clearing it.
I looked at the QuickBooks SDK (we use the XML to communicate in general) and It references a field on the check called PayeeEntityRef with a FullName property, but typically in QuickBooks that data structure would indicate what the entity is called, not what appears on the check (Vendors have a NameOnCheck property, for example, which can be something other than their name).
Without coding up multiple test cases to demonstrate QuickBooks behavior here, does anyone have experience with getting the name as it was printed on the check? What is the best way to do it?
It's somewhat possible to get what you are wanting, but there are going to be some hiccups that you'll need to let you client know about. The main problem being that there's no way to retrieve the actual name printed on the check.
You would first need to query for the Checks/Bill Payment - Checks for the bank account. Then, using the PayeeEntityRef (I would use the ListID component) figure out which "List" the entity is on; Customer, Vendor, Employee, or Other. I don't know of any way to tell which list the PayeeEntityRef is from other than doing a query for each of the lists.
If the PayeeEntityRef is a Vendor or Employee, then you can retrieve the NameOnCheck value. The only thing you would need to keep in mind is that if the NameOnCheck has been modified AFTER the check was printed, the names will not match.
If the PayeeEntityRef is a Customer or Other name, then you have to do a little bit more. The value that QuickBooks uses for the printed name is based on what fields are filled out for the customer record. It first will use the CompanyName field if it is not null. Next, it will try to use the First/Middle/LastName fields, if they are not null. Finally, it will use the Name field as a last resort. Keep in mind that this is not the FullName field, just the Name field.
I haven't tested this with an "Other" name, as I have my clients try not to use that list, but I would imagine it's similar to how Customers work.