Tuesday, 5 August 2014

Calling a Service from a Report

The reporting framework in IBM BPM provides a good platform for building real-time reports & dashboards but this is often not what I use them for. The Report & Scoreboard components provide a container for serving any custom HTML pages to the user via the portal. Frequently, I end up using reports to build custom inboxes or custom landing pages instead of going to the default inbox.

To be able to build these pages you will need to know how to use the report & JavaScript APIs to your advantage. These will allow you to utilise many of the components and services already constructed in IBM BPM. One of the core pieces of functionality is being able to call services from a report page.

There are 2 main ways to call a service from a report.

Calling a Service from Server Side

By using the <#= #> notation, you can call a service from the Server Side by using the JavaScript API.

The following code snippet, is an example of calling a service to return a list of cities. This is then used to build options which are later added to a dropdown list to be rendered on the page.
<#
// Execute Service "Retrieve Cities" with no params (empty map)
var outVars = tw.system.model.findServiceByName("Retrieve Cities").execute(new tw.object.Map());

//Retrieve the output variable "cities" which contains a list of NameValuePairs
var cities = outVars.get("cities");

var cityOptions = "";

//Loop through each city and create an "option" appended to the cityOptions String
for(var i = 0; i < cities.length; i++){
    cityOptions += "" + cities[i].name + "";
}
#>

This will only execute when the page loads, so it is useful for content that will stay the same throughout the life of the page. To execute it again you would need to reload the page again. For this to use user customisable parameters (filters for example) you would need to use report filters in the URL which can often be fiddly. These are often a necessity, especially if you changing report pages.


Calling a Service using AJAX

The second way to call a service from a report in IBM BPM is to use AJAX. This allows you to call a service and return the result without having to reload the page. Built into the product is a wrapper JavaScript function called "tw.coach.callService" which performs the AJAX call to a service. This is used by the AJAX controls in the coach designer. Although this is not publicised as a supported API, it is fairly widely used to call services via AJAX in both reports and from coaches. The following code snippet is an example of calling the service “Save Input” passing the parameters “input1” and “input2”. These represent the input variables of the service being called.
//Setup Inputs
var vars = ""
    + "" + document.getElementById('input1').value + ""
    + "" + document.getElementById('input2').value + ""
    + "";

//Make AJAX call to Service "Save Input"
tw.coach.callService("Save Input", vars,
    //Call Back Function
    function(data){
        if(data.returnValue == undefined){
            alert("Error calling 'Save Input' Service");
        }else{
            //Process Values
        }
    },
    '<#= tw.system.model.processAppSnapshot.id #>');
The function specifies a return function which is called with the output values of the service (if any). The <#= tw.system.model.processAppSnapshot.id #> as the last parameter of the AJAX function call specifies the snapshot ID of the process app where the service resides. In the example above, this is assuming that that service is in the same process app. If the service is in a different process app, you will need to use this, where "ACRONYM" is the short name given to the process app:
tw.system.model.findProcessAppByAcronym("ACRONYM").currentSnapshot.id