How to get item table values using OData Model? - odata

I have a OData model and data is as follows
Here, Under ZRECRUITMENT_TRACERRzSet(1), I have "toCandidates" which is Association and it has item level data.
How can I access it's values in the controller.
I tried using
oModel.getProperty('/ZRECRUITMENT_TRACERRzSet(1)/toCandidates')
But it's not helping.

You need to set the 'expand' property in your binding, so whenever the request is sent to the OData service, the "toCandidates" node will come with the data in the response, and not the URL only. Then your getProperty(...) will give you the data.
Whenever you are binding your data you need to do something like this (for example with ElementBinding):
oMyControl.bindElement({
path: "/ZRECRUITMENT_TRACERRzSet(1)",
parameters: {expand: "toCandidates"}
});

Related

multiple exclude data can't catch in filter option odata

I create smart table sapui5 screen by using odata (S4Hana) .
On the odata side, get the filter value from smart filter by using this method ⇒ [ io_tech_request_context->get_filter( )->get_filter_select_options( ).]
It is ok when I pass the filter value as multiple Include option .
When I pass the filter value as multiple Exclude option , the data can't access from filter_select option method. The data can be get in filter_string method but it is difficult to get the data and put to range table .
Let me know how to get the filter value from entity set of odata .
Let me know how to get the filter value from entity set of odata .
There are defined rules, how your $filter parameter has to look like to get converted into the import parameter it_filter_select_options. If you breach this rules (you did...) the import parameter it_filter_select_options will be empty.
Sadly, there's no simple solution.
If you need to convert the parameter iv_filter_string into select options there are quite a few Tutorials/Blogs about it.
Filter String How To
How to Parse IV_FILTER_STRING in GET_ENTITYSET

SAPUI5 TreeTable Node Expansion Still Calling OData

Is there a way for the SAPUI5 TreeTable to not call the OData web service on each node expansion? I've tried setting the operationMode parameter to client as part of the data binding, but it still retrieves the data via individual web service calls for each node expansion. Currently running SAPUI5 1.28.45.
The model is of type sap.ui.model.odata.v2.ODataModel and set globally. I've tried configuring the default operation mode on the model without success and toggling batch mode without success. It's set up for two-way binding as well.
I'm currently setting the operation mode as below with no luck:
this._oTable.bindRows({
path: '/EventSet',
filters: self._aFilters,
parameters: {
countMode:'Inline',
operationMode: sap.ui.model.odata.OperationMode.Client // Seemingly ignored
}
});
You could try to use JSONModel Binding instead of ODataModel Binding.
You can get the content of the EventSet with a Read function https://sapui5.hana.ondemand.com/#docs/api/symbols/sap.ui.model.odata.v2.ODataModel.html#read
Then in the Success function you take the result, create the JSONModel, convert the data into something that the TreeTable can use, set this to the JSONModel, set the JSONModel to your TreeTable Object (eg.):
this._oTable.setModel(oYourJsonModel, sModelName);
this._oTable.bindRows({
path: "/",
parameters: {
arrayNames: ["additionalData"]
}
});
Here you can find information about JSON Tree Binding:
https://sapui5.hana.ondemand.com/explored.html#/sample/sap.ui.table.sample.TreeTable.JSONTreeBinding/preview
Hope it helps.
Best regards,
Adrian

What is the difference between new sap.ui.model.odata.ODataModel and read?

I am playing around with a OData service and I am very confused when to use this
var oModel = new sap.ui.model.odata.ODataModel("proxy/http/services.odata.org/V3/(S(k42qhed3hw4zgjxfnhivnmes))/OData/OData.svc");
this.getView().setModel(oModel);
vs
var oModel = new sap.ui.model.odata.ODataModel("odatserviceurl", true);
var productsModel = new JSONModel();
oModel.read("/Products",
null,
null,
false,
function _OnSuccess(oData, response) {
var data = { "ProductCollection" : oData.results };
productsModel.setData(data);
},
function _OnError(error) {
console.log(error);
}
);
this.getView().setModel(productsModel);
I have two working example using both approach but I am not able to figure out why using read method if I can achieve same with first version. Please explain or guide me to the documentation which can clear my confusion.
Ok, lets start with the models:
JSON Model : The JSON model is a client-side model and, therefore, intended for small datasets, which are completely available on the client. The JSON model supports two-way binding. NOTE: no server side call is made on filtering, searching, refresh.
OData Model : The OData model is a server-side model: the dataset is only available on the server and the client only knows the currently visible rows and fields. This also means that sorting and filtering on the client is not possible. For this, the client has to send a request to the server. Meaning searching/filtering calls odata service again.
Now, lets look at scenarios where we will use these models:
Scenario 1: Showing data to user in a list/table/display form. Data manipulation is limited to searching and filtering. Here, I would use oData model directly to controls as only fetching of data is required.( your method 1) (NOTE: One way binding). Remember here all changes require a call to server.
Scenario 2: I have an application which has multiple inputs, user can edit changes, also some fields are calculated and mandatory. All in all, many user changes are done which may be temporary and user might not want to save them. Here, you dont want to send these temporary changes to backend as yet. You way want to manipulate, validate data before sending. Here, we will use JSON Model after reading data from odata model ( your method 2). Store the changes in local JSON model, validate and manipulate them and finally send the data using Odata create/update. Remember here all changes DO NOT require a call to server as data is present in local JSON MODEL.
Let me know if this helps you. :)
EDIT : Additional Information :
As per your comment :
Documentation says oModel.read' trigger get request but new sap.ui.model.odata.ODataModel("proxy/http/services.odata.org‌​/V3/(S(k42qhed3hw4zg‌​jxfnhivnmes))/OData/‌​OData.svc")` does the same thing so why and when to use oModel.read
Here, is where you misunderstood. The code
new sap.ui.model.odata.ODataModel("proxy/http/services.odata.org‌​/V3/(S(k42qhed3hw4zg‌​jxfnhivnmes))/OData/‌​OData.svc") will NOT send a read/get Request. It calls the odata services and fetches the metadata of the service. A service can have multiple entities.
For example: the service :http://services.odata.org/Northwind/Northwind.svc/ has mutiple entity sets such as Categories, Customers, Employees etc. So, when I declare : new sap.ui.model.odata.ODataModel("http://services.odata.org/Northwind/Northwind.svc/") it will fetch the metadata for service (not actual data). Only when you call the desired entity set, it will fetch the data. The Entity set is specified :
When you call the read method ( like you have specified '/Products')
Bind the entity set name directly to control like to List,Table etc ( items='{/Products}' )

RestKit POSTed managed object becomes duplicate when response is enveloped in an array

When I POST a Core Data managed object using RestKit, RestKit doesn't update the existing object but creates a new object instead.
The returned JSON always contains the newly created object, but wraps it into a plural keyed array. I found that if I change this to just the one object, the updating works as expected. However, I would like to keep the array in the response so that all responses are consistently in the plural form.
Is there any way I can make RestKit update the record, even when returned from the server wrapped in an array?
Possible solution: identificationAttribute?
On my entities I have an identificationAttribute called remoteID. This is the primary unique key of the record. This will be 0 before the POST, because the object is not yet on the server. I thought that by adding a second identificationAttribute called insertionID, setting that before the POST, and then returning it in the response, would allow RK to find the existing entity in the local store. Alas, it didn't work.
What did work however, was setting the remoteID before the POST, to the next auto increment value on the server! What could explain that it works with remoteID, but not with a second insertionID?
Example request
{
"user": {
"email": "example#example.com"
}
}
Response
{
"users": [{
"email": "example#example.com"
}]
}
I would like to keep the array in the response so that all responses are consistently in the plural form.
You shouldn't, because this is an individual request and response, not a composite.
Your idea about identificationAttribute is correct, but doesn't apply when the response is an array. The array is the trigger (or one of the possible triggers) to abandon the match with the source object and create new objects. Changing this would be hard.
Without knowing more about your real situation, 2 alternatives:
Change the JSON
POST a dictionary instead of the real object and then you won't have a duplicate
When you use multiple identification attributes, all must match for the destination object to be found.
Take care - don't create multiple mappings for the same entity with different identification attributes or you will most likely be debugging the lookup cache for a long time trying to work out what's happening...
If the identity matches before the request is made then the array isn't an issue. To explain the above in more detail:
When you POST an object, RestKit expects to get that object back. So, if you POST one object and get an array back it doesn't know what to do, because it can't map an array into an object. So, it tries to lookup based on the identification attribute (if they exist). If the POSTed object didn't have an id and the returned object does then it will never match. If you set it before POSTing then it will match.

RestKit 0.20 and ManagedObjectContexts

I am mapping data using RestKit 0.20 into a Core Data and displaying it in a UITable. I am writing the data, an 'Activity' object, to the mainQueue's ManagedObjectContext and it all works fine. Now I need a second table with Future-Activities and also a third table with Past-Activities. I need a ManagedObjectContext for each table as the sorting is done on the server side. How can I handle this and have persistent data. Is 'newChildManagedObjectContextWithConcurrencyType' what I need to use?
Keep a single store. Use a predicate to filter out the items you want.
If you can download all of the data (and you're happy to do that even though some of it may not be used by the user), and you can tag them for what they are used for then that is an option.
From a RestKit point of view, you can use metadata to tag the items during the mapping process so that you know how they should be used (and then filter on that). This requires that you add a new key to the item - but, if one item could be in all responses this will be problematic because the values would get overwritten.
To use metadata, simply add a new mapping like:
#"#metadata.URL": #"requestURL"
Where #metadata.URL is the URL used to make the request and requestURL is the property on your entity that you can use for filtering. The predicate will check for contains your types ("all_day" "start_time" "end_time").

Resources