Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Caspar_van_t
Explorer
This blog post describes how you can apply deep filtering in your SAPUI5 application, using CAP and odata V4. This can be used to filter in expanded entities, which has come available in V4. Please note that using an oData V2 model to do this will not work, since this type of filtering is not supported in the odata v2 model.

 

1. Introduction


Most SAPUI5 applications consume an oData service, which is often built using the CAP framework. Using this framework, you are able to create linked entities, called associations. In specific scenario's you might want to be able to filter in associated entities, while only retrieving the main list. For example, if you have the (very simplistic) below model:


Imagine these are entities in your CAP service, and Car has association links to Windows and Wheels, and you want to filter on cars that have specific windows installed in them. In this scenario, we would like to filter out those cars, using a deep filter (on the expanded entity properties).

 

2. Prerequisites


You will need a couple of things set up before being able to do this. Lets start with setting up our service the correct way, using an association;
U_to_Wheels : Association to many Wheels
on U_to_Wheels.ID = Wheels.ID;

More information on associations can be found in the documentation here.

 

Once we have a valid cap services, with our associations in place, we can start using them in our SAPUI5 application. Lets start by setting up our application to use an odata V4 model (in our manifest.json);


 

3. The filtering itself


Next we need to make sure that when we select our filter on our table, we define our filter just a little different then we are used to;
new Filter({
path: "U_to_Wheels", // The name of your expanded entityset
operator: FilterOperator.Any, // Can be any or all, defines which records have to apply to your filter
variable : "U_to_Wheels", // Also the name of your expanded entityset
condition : new Filter("U_to_Wheels/ID", FilterOperator.EQ, "1") // The condition you want to filter on
})

 

Once we apply this filter, we will see an oData call which should look like this:
GET Cars?expand=U_to_Wheels&$filter=U_to_Wheels/any(U_to_Wheels:U_to_Wheels/ID eq '1')

The filtering should be applied, and you can query expanded entities.. Hurray!!

Please note that we applied FilterOperator.Any in this case, which should return all MAIN records that have ATLEAST 1 wheel with ID 1 in the expanded set. We can also switch the FilterOperator.All which returns the MAIN records that ONLY have wheels with ID 1 in the expanded entity set.

 

4. Possible issues


When switching over to the required oData V4 model from an existing oData V2 model (which was the case in my journey), you might run into some issues. Here I will highlight some that I have ran into, and how to solve them;

When switching to the V4 model, some bindings require an explicit TargetType (which states what 'type' the binding should be, i.e. string, number, etc.). There is an 'all' variant available, which makes it accept all types like so;


 

 

When using the V4 model, some functions are not available anymore, for example the attachRequestFailed function. Previously, we have the following code implemented (which broke):
this.getModel().attachRequestFailed((oEvent) => {
ServiceCaller.handleDefaultRequestFailure(oEvent.getParameter("response"));
});

To fix this, we implemented the same functionality as follows:
this.getModel().attachDataReceived((oEvent) => {
if(oEvent.getParameter("error")){
ServiceCaller.handleDefaultRequestFailure(oEvent.getParameter("error"));
}
});

 

 

Another error that I encountered is that the .read() function is no longer available on the V4 model. This is logical, since you would like to do all service calls using bindings instead of fetching things in code. You can use things like $.get to work around it if strictly needed, but this is bad practice.

 

5. Concluding


Now you should know how to do some deep filtering on expanded entities, using the oData V4 model. In case of any questions, please leave a comment. Happy coding!
4 Comments
robdejong
Explorer
0 Kudos
Nice one Caspar!
leonvanginneken
Explorer
0 Kudos
Indeed!
former_member250354
Discoverer
0 Kudos
Indeed indeed!
MathiasUhlmann
Advisor
Advisor

Hi Caspar,

thanks for this blog post highlighting an important feature of OData V4!

Let me add a few things:

  • Model parameter "synchronizationMode": This parameter has become optional and deprecated with SAPUI5 1.110. It had turned out that the use case for which this parameter had been reserved is getting solved differently.
  • Our documentation on Filtering also explains ANY and ALL filters.
  • We documented how to access data in controller code. You may also have a look at this blog post of Wouter Lemaire as well.
  • As to using the "dataReceived" event for performing some generic error activity: The general idea is to provide one or more messages in the OData error response that explain to the user what went wrong. The ODataModel parses these messages and makes them available in the MessageModel of UI5. See also Server Messages in the OData V4 Model. The application would then react to the change event raised by the list binding created on the message model.

Best regards
Mathias.

Labels in this area