How to access UI5 model data

Old habits are not easily dying and replaced by best practices and general recommendations. In the early days, when UI5 started to gain traction, people discovered it, tried it out, wrote apps, made them somehow work. Everybody was learning, and things we can do today were not possible or known then. Changes to the documentation, API and recommendations are simply the result of lessons learned.

As UI5 apps are based around a model, its data, representation and manipulation, a lot of questions around UI5 development are about the model: how to access data, change, update or delete it. A good thing of UI5 is that it is following semantic versioning, and code written for UI5 1.1x or 1.2x will still work with latest versions like 1.5x. It doesn’t mean that you, as a developer, should simply copy & paste example code found somewhere.

Example

After loading the model, be it JSON or OData, you may have to access a specific property in you code. What you can find in the Internet is code like:

oData

var oData = this.getView().getModel().oData;
var firstname oModel.getModel().oData[entity].firstname;
var name = oData[entity].name;

JSON

var oData = this.getView().getModel(“device”).oData;
var osname = oModel.oData.os.name;
var osname = this.getView().getModel().getData().os.name;

First line will give you the model data object, 2nd and 3rd line the property osname of the model. The 3rd line is partly correct, as the access to the data is done through a method, but access to property name is done directly. You can work with the data object now directly, but you shouldn’t. What you want is not to work with the raw data that defines your model, but with properties.

Use access methods

Data binding is important when developing an UI5 app. You update properties, and you want to have the UI elements automatically be updated too. When accessing the properties directly, you have to check if the change is correctly propagated. Using access methods, UI5 will for sure take care of this. The method to access properties of your data model are getData, getProperty or getObject. Applying this to above code:

JSON

var oData = this.getView().getModel().getData();
var osname = this.getView().getModel(“device”).getProperty(“/os/name”);

OData

var entity = this.getView().getModel().getObject("/"+key);
var property = this.getView().getModel().getProperty("/"+key+"/Depth");

This is now only using the methods to access data. To alter the property, use the setProperty method.

OData

this.getView().getModel().setProperty("/"+key+"/Depth", 11.111)

JSON

this.getView().getModel("device").setProperty("/os/name", "windows")

The above examples may not be perfect. They show that UI5 offers methods to access model data. Using these methods your code will continue to work in the future and is guaranteed to work in future releases of UI5. Direct access to the model data is done at your own risk. In case you work on a UI5 app, use the access methods. If you work on an older app that uses direct access to the model, try to refactor the app. The change from oModel.oData to oModel.getData() is as simple as executing a find and replace.

 

Expose a BAPI using JSON and REST

Note: 1st published on SCN at 22.5.2012

 

REST.

JSON.

These are the technologies you need when writing modern web applications. And that is what makes it so hard to use SAP together with modern web applications: Currently you only get REST from SAP with Gateway, but not JSON. OData comes from Microsoft and support is not as wide spread as someone expects. How OData does looks like? You can try it out by downloading the Gateway Trial from SCN or use the online demo system. To experiment with Gateway the usual flight example from SAP can be used. To get the details of a specific flight: sap/opu/sdata/iwfnd/RMTSAMPLEFLIGHT/FlightCollection(carrid=’AA’,connid=’0017′,fldate=’20110601′)

Data returned from Gateway looks like this:

Instead of being able to use the data exposed by Gateway by the widely used Javascript frameworks like jQuery you need to find an OData plugin. Of course you can still use SAP UI5, but what when you are forced to use jQuery, Sencha, Dojo or something else?

That’s a problem with SAP and ABAP in general: you have to wait until SAP or developer implements functionality, and because of the limit resources available in the ABAP ecosystem this can take a while, costs some serious amount of money or will never happen. That’s where we can be happy that SAP also embraces the use of Java. As Java was made for the internet there is a huge Java community out there that most probably already developed a tool that fits your needs.

For exposing data as JSON in a REST-full way the tool available is: Jersey.

After Jersey transformed the data, the response looks like:

{“EXTENSION_IN”:{“item”:[]},”EXTENSION_OUT”:{“item”:[]},”RETURN”:{“item”:[{“TYPE”:”S”,”ID”:”BC_IBF”,”NUMBER”:”000″,”MESSAGE”:”Method was executed successfully”,”LOG_NO”:””,”LOG_MSG_NO”:”000000″,”MESSAGE_V1″:””,”MESSAGE_V2″:””,”MESSAGE_V3″:””,”MESSAGE_V4″:””,”PARAMETER”:””,”ROW”:0,”FIELD”:””,”SYSTEM”:”NPLCLNT001″}]},”ADDITIONAL_INFO”:{“FLIGHTTIME”:361,”DISTANCE”:2572.0000,”UNIT”:”MI”,”UNIT_ISO”:”SMI”,”PLANETYPE”:”747-400″,”FLIGHTTYPE”:””},”AVAILIBILITY”:{“ECONOMAX”:385,”ECONOFREE”:20,”BUSINMAX”:31,”BUSINFREE”:1,”FIRSTMAX”:21,”FIRSTFREE”:3},”FLIGHT_DATA”:{“AIRLINEID”:”AA”,”AIRLINE”:”American Airlines”,”CONNECTID”:”0017″,”FLIGHTDATE”:1306897200000,”AIRPORTFR”:”JFK”,”CITYFROM”:”NEW YORK”,”AIRPORTTO”:”SFO”,”CITYTO”:”SAN FRANCISCO”,”DEPTIME”:50400000,”ARRTIME”:61260000,”ARRDATE”:1306897200000,”PRICE”:422.9400,”CURR”:”USD”,”CURR_ISO”:”USD”}}

Jersey needs Java 6 and runs in a servlet container. As NetWeaver CE >= 7.2 fulfills these requirements, Jersey can be used to transform POJOs into JSON and expose them using REST. NW CE comes with a framework for creating composite applications (CAF) that can consume BAPIs. CAF uses standard J2EE technology like JCA and Beans. This bean can be used by Jersey to automatically extract the data, transform it into JSON and make it accessible using REST.

Consuming a BAPI using CAF can be done with no coding involved at all as CAF comes with some nice wizards. Just map the input and output parameters and the code will be generated including the bean that can be used to interact with the BAPI. In the Jersey web application the URL and protocol get defined:

@GET

@Path(“getFlight/carrid/{carrid}/connid/{connid}/fldate/{fldate}”)

@Produces(“application/json”)

The CAF bean gets called using the parameters retrieved from the URL:

out = e.bapiFLIGHTGETDETAIL(null, null, null, carrid, connid, flightDate);

That’s it. Jersey will do the rest:

How the URL gets constructed is up to you, the parameters can be part of the URL as above or a query. You can also define if it is GET, POST, PUT, etc. If you want to do some coding you can adjust the output, or combine the result of several BAPIs into one Java object that JSON will expose.

Now that the BAPI can be accessed in a RESTful way and the data retrieved is in the JSON format, it’s easy to use the data in a Javascript framework like jQuery with Datatables:

The actual coding for making the CAF bean accessible to Jersey and expose the data is less than 10 lines of code. From CAF to Jersey to a running HTML application it does not even take 30 minutes.

The framework I used for interacting with the ABAP system is CAF, a framework available for NetWeaver Java since a while (7.0): well documented enterprise ready and supported. If you want or need to expose your BAPI by REST and JSON or XML and you have a NetWeaver CE >= 7.2 (like Portal 7.3) available, you can start today. As your NW CE system is a separate one, upgrades won’t affect your backend system and as Jersey is also a separate application; changes to Jersey don’t affect your other CE server and applications. Of course you don’t need NW CE for using Jersey and CAF for interacting with BAPI. Every platform that Jersey supports and where you can use JCo from SAP to call a BAPI can be used like tomcat. It just means that some extra configuration and coding will be necessary. This also implies that your backend ABAP system can be used as long as a JCo connection to it is possible.