logo

NJP

How to refresh Service Portal widget data when backend data changes

Import · Jan 10, 2019 · article

Service Portal provides spUtil (which then calls snRecordWatcher) to refresh a record when there is a change in the backend

spUtil.recordWatch($scope, "incident", "sys_id=" + sysId, function(name, data)

{

getIncidentRecord($scope,c,sysId);

});

But, we can not use this to fetch a list of records which is a pretty common scenario for Dashboard or Table data refresh in real time. We can take advantage of $interval service provided by AngularJS to achieve this. Specify the refresh interval here (I set it to 3 seconds)

$interval(function() 
{
    c.getData();
}, 3000,0);


Widget HTML:

        <div class="x_content">
          <div class="col-md-12  col-sm-12 col-xs-12 table-responsive"   -ng-controller="myIncidentsController">
            <table ng-table="tableParams" class="table table-condensed table-bordered table-striped" >
              <tr ng-repeat="row in $data track by $index" >
                <td data-title="'#'" class="cell"  filter="{ incidentIndex: 'number'}" sortable="'incidentIndex'">{{row.index}}</td>
                <td data-title="'Incident Id'" class="cell" filter="{ incidentId: 'text'}" sortable="'incidentId'"><a href="/haloportal?id=incident_summary&incident_id={{row.sysId}}" style="color:#0c4a6f" >{{row.incidentId}}</a></td>
                <td data-title="'Incident Urgency'"   filter="{ urgencyRank: 'text'}"  sortable="'urgencyRank'" class="cell">{{row.urgencyRank}}</td>
                <td data-title="'Incident Type'"  filter="{ incidentType: 'text'}" sortable="'incidentType'" class="cell">{{row.incidentType}}</td>
                <td data-title="'Incident Status'"   filter="{ incidentStatus: 'text'}"  sortable="'incidentStatus'" class="cell">{{row.incidentStatus}}</td>
                <td data-title="'Indicator Count'"   filter="{ indicatorCount: 'number'}"  sortable="'indicatorCount'" class="cell">{{row.indicatorCount}}</td>
                <td data-title="'Created Date'"   filter="{ createdDate: 'text'}"  sortable="'createdDate'" class="cell">{{row.createdDate}}</td>
                <td data-title="'Last Updated'"   filter="{ lastUpdated: 'text'}"   sortable="'lastUpdated'" class="cell">{{row.lastUpdated}}</td>
              </tr>      
            </table>
          </div>

        </div>

Widget Client Script:

function($scope, $http, $location, $log, $upload, $timeout, $rootScope, $q, $interval,  spUtil, spAriaUtil, nowAttachmentHandler,nowServer, spModal) 
{

  var c = this;
    c.getData = function() 
    {
    c.server.get({method:'getRightWidgetData'}).then(function(response)
        {
            c.data.myIncidentsData=angular.fromJson(response.data.myIncidentsData);
            $scope.$emit("myIncidentsDataReady", c.data.myIncidentsData);
        });
   };

//Calls getData() when page loads initially
c.getData();

//Refresh data every 3 seconds
$interval(function() 
  {
    c.getData();
  }, 3000,0);


Widget Server Script:

(function() 
 {
        //Do not remove this line. Client calls Server Script multiple times and increaes load time if 'input' value not checked
        if(input)
        {
            if(input.method == 'getRightWidgetData')
            {
                var rightWidgetUtils=new RightWidgetUtils();
                data.myIncidentsData=rightWidgetUtils.getMyIncidentsData();

                data.userData=rightWidgetUtils.getUserData();   
            }

        }
})();

UI Script (Add this a dependency to Widget):

(function() 
 {
    "use strict";
    var app=angular.module("RightWidgetAnalyst", ["ngTable"]);


    //myIncidentsController
    app.controller("myIncidentsController",["$scope","$rootScope","NgTableParams",function($scope,$rootScope,NgTableParams)
                            {

                                /*
                                    NgTableParams constructor => new NgTableParams(baseParameters?: IParamValues<T> | boolean, baseSettings?: ISettings<T>): NgTableParams
                                    See this => http://ng-table.com/api-docs/classes/ngtableparams.html#settings
                                */
                                $rootScope.$on("myIncidentsDataReady", function(data)
                                {
                                    $scope.dataset = data.targetScope.data.myIncidentsData;

                                    var baseParameters={count:10,sorting:{incidentId:"desc"}};
                                    var baseSettings={dataset: $scope.dataset,counts:[10,25,50,100],paginationMinBlocks:2,paginationMaxBlocks:13};

                                    $scope.tableParams = new NgTableParams(baseParameters,baseSettings);
                                }); 

                                //Filter Table based on clicked Badge
                                 $rootScope.$on("myIncidentsTableFilterValue", function(data,myIncidentsTableFilterValue)
                                {
                                    $scope.dataset = data.targetScope.data.myIncidentsData;

                                    var baseParameters={count:10,sorting:{incidentId:"desc"},filter:{urgencyRank:myIncidentsTableFilterValue}};
                                    var baseSettings={dataset: $scope.dataset,counts:[10,25,50,100],paginationMinBlocks:2,paginationMaxBlocks:13};

                                    $scope.tableParams = new NgTableParams(baseParameters,baseSettings);

                                }); 

                            }]);


})();

Note:

I am using ng-table data grid to display data on the page and you should add their library as a dependency to make this work. It's a pretty good library and customizable. Check out their API for more information.

View original source

https://www.servicenow.com/community/developer-articles/how-to-refresh-service-portal-widget-data-when-backend-data/ta-p/2330250