Service Portal Record Watcher

The Service Portal record watcher is a Service Portal utility available for use in the client controller of your service portal widgets. This function gives you the ability to live query a table whenever it is updated in order to provide updates in real time in your widgets. For example, if you wanted to build a report widget but needed it to refresh live without having to manually reload the page, the record watcher can re-run the server script in the background and refresh the widget details. In the example below, we use the record watcher with a query against the sysapproval table. If the related task matches the sys ID of the current record being viewed in the widget, run the server script in the widget and then update any data objects in the scope.

 

spUtil.recordWatch($scope, 'sysapproval_approver', 'sysapproval=' + $scope.data.req_id, function(name, data) {
        $scope.server.update().then(function(response) {
                $scope.data.myValue = true;
                spUtil.update($scope);
        });

});

 

If you are calling any data objects from the scope in your HTML elements, spUtil.update($scope) is required in order to refresh the values tied to your elements. For example, if one were to use an “ng-if” or “ng-show” in your attributes in order to show or hide an element that shows approvals tied to a request or task, you would set a data object to true or false. Code in the server script portion of your element will run on load and determine whether or not to show the widget. Let’s say for example, you submit a request and at first there are no approvals and so your custom approval list widget does not show. Upon submission, we want the widget to show the approval that gets generated without refreshing the page. The server script would look something like this:

 

var has_approval = false;
var req_id = $sp.getParameter('sys_id');
var grApproval = new GlideRecord('sysapproval_approver');
grApproval.addQuery('sysapproval', req_id);
grApproval.query();
if(grApproval.next()) {
        has_approval = true;
}
data.req_id = req_id;
data.myValue = has_approval;

*Note: Notice that we do not directly set data objects and then reset them based on the gliderecord conditional. As a best practice, use variables and then set the data.<name> after the variable value is determined.

 

This script will run on load and determine if myValue is true or false. The parent element for your custom approval widget would have an ‘ng-if=myValue’, so if an approval exists, the widget will display. In our use case, we start with no approvals but want to display our widget and have our approvers/approvals and their status refresh in real time. Once the approval record is created, our record watcher script will be looking for a record where the ‘sysapproval’ field sys_id is our req_id data object and then run the server script and refresh the scope. We get the sys ID of the record by grabbing it from the URL parameter ‘sys_id’ using $sp.getParameter(). When a record is created, updated, or deleted on our selected table and matches our query, the record watcher util will force the widget to display the new information.

The parameters for the record watcher are as follows: The first is always $scope which indicates the scope of the widget. Then the name of the table to query, followed by an encoded query against that table.

spUtil.recordWatch($scope, 'table_name', 'encoded_query', function(name, data)

It is extremely important that you add a query for the third parameter that targets records as specifically as possible. If there is no query, the table is queried every time any record on the table changes. This can lead to performance issues on the portal page that can affect the response time of other widgets and the instance in general. In our example we used the approval table. This table may be small after an implementation but over time will grow very large, causing a record watch with no query to run extremely slow. As a best practice, always include a specific query.