Angular is not defined in Widget - Service Portal

jpavanaryan
Tera Expert

I created widget in Service Portal and with HTML, Client script & Server script as shown below. However I am getting this strange error in client script saying "angular" not defined (I think Angular JS library file loaded by ServiceNow by default)

Screen Shot 2017-04-18 at 10.26.36 AM.png

HTML Template:

<div ng-app="myApp" class="container-fluid">

  <div class="row">

  <div class="col-md-12" ng-controller="demoController as demo">

      <h3>Open Incidents</h3>

      <table ng-table="demo.tableParams" class="table table-condensed table-bordered table-striped" ng-init="this.getData()">

          <tr>

              <th>Incident Id</th>

              <th>Incident Type</th>

              <th>Status</th>

              <th>Indicator Count</th>

              <th>Created Date</th>

              <th>Last Updated</th>

          </tr>

          <tr ng-repeat="row in c.data.tableData track by $index">

              <td data-title="'incidentId'" sortable="'incidentId'">{{row.incidentId}}</td>

              <td data-title="'incidentType'" sortable="'incidentType'">{{row.incidentType}}</td>

            <td data-title="'incidentStatus'" sortable="'incidentStatus'">{{row.incidentStatus}}</td>

              <td data-title="'indicatorCount'" sortable="'indicatorCount'">{{row.indicatorCount}}</td>

              <td data-title="'createdDate'" sortable="'createdDate'">{{row.createdDate}}</td>

              <td data-title="'lastUpdated'" sortable="'lastUpdated'">{{row.lastUpdated}}</td>

   

          </tr>

      </table>

  </div>

</div>

</div>

Client Script:

function()

{

  "use strict";

  var c = this;

  var app = angular.module("myApp", ["ngTable", "ngTableDemos"]);

  app.controller("demoController", demoController);

  demoController.$inject = ["NgTableParams", "ngTableSimpleList"];

  function demoController(NgTableParams, simpleList)

  {

  c.tableParams = new NgTableParams({

  // initial sort order

  sorting: { incidentId: "asc" }

  }, {

  dataset: simpleList

  });

  }

  c.getData = function()

  {

  c.server.get().then(

  function(response)

  {  

  c.data.tableData= angular.fromJson(response.data.tableData);

  })

  };

  c.getData();

}

1 ACCEPTED SOLUTION

In service portal, angular dependencies should be placed in dependencies as shown images at the bottom. These dependencies are UI scripts with the standard syntax. Updated code as follows.



$scope.$emit("dataReady",c.data.tableData);



The above statement in Widget Client Controller Sends data to dependency/script. $scope.dataset = data.targetScope.data.tableData; in Open Incidents UI script catches it. These are standard angular functions to emit and catch data. Look at angularjs dicumentation for more information https://docs.angularjs.org/api/ng/type/$rootScope.Scope



Widget HTML:



<div   class="container-fluid">


  <br/>


  <div class="panel panel-info">


   


      <div class="panel-body">




          <div class="col-md-12 table table-responsive" -ng-controller="myCtrl">


              <table ng-table="tableParams" class="table table-condensed table-bordered">


                  <tr ng-repeat="row in $data track by $index" >


                      <td data-title="'#'" class="cell"   filter="{ incidentIndex: 'number'}" sortable="'incidentIndex'">{{$index+1}}</td>


                      <td data-title="'Incident Id'" filter="{ incidentId: 'text'}" sortable="'incidentId'"><a href="/haloportal/?id=incident_summary&incident_id={{row.sysId}}" style="color:#0c4a6f"   target="_self">{{row.incidentId}}</a></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>


  </div>


</div>




Widget Client Script:



function($scope)


{


var c=this;


c.getData = function()


{




c.server.get().then(


function(response)


{


c.data.tableData= angular.fromJson(response.data.tableData);


$scope.$emit("dataReady", c.data.tableData);


})


};


c.getData();


}




Widget Server Script:


(function()


{


var json=new global.JSON();


var list=[];


var i=1;


var gr=new GlideRecord('x_19668_halo_incident');


gr.orderByDesc('incident_id');


gr.query();


while(gr.next())


{


list.push({incidentIndex:i++,incidentId:gr.incident_id+'',incidentType:gr.incident_type.name+'',indicatorCount:gr.complted_indicator_count+'',incidentStatus:gr.ticket_status+'',createdDate:gr.sys_created_on+'',lastUpdated:gr.sys_updated_on+'',sysId:gr.sys_id+''});


}



data.tableData=json.encode(list);


})();




Open Incidents UI Script:


(function()


{


"use strict";


      var app=angular.module("openIncidentsModule", ["ngTable"]);



//We are not using this service anymore


app.service('myService',function()


{


//var c=this;


this.getData2=function()


{


var jsonList = JSON.parse(sessionStorage.getItem('jsonListString'));


sessionStorage.removeItem('jsonListString');


return jsonList;


};




});



//Controller


app.controller("myCtrl",["$scope","myService","$rootScope","NgTableParams",function($scope,myService,$rootScope,NgTableParams)


{


var jsonList;


      $rootScope.$on("dataReady", function(data)


{


$scope.dataset = data.targetScope.data.tableData;


$scope.tableParams = new NgTableParams({count:20,sorting:{lastUpdated:"desc"}},{dataset: $scope.dataset,paginationMinBlocks:2,paginationMaxBlocks:13});


}); //End of rootScope



}]);


      /*


angular.module("openIncidentsModule").run(configureDefaults);


function configureDefaults($scope,ngTableDefaults)


{


ngTableDefaults.params.count = 15;


ngTableDefaults.settings.counts = [];


}


configureDefaults.$inject = ["$scope","ngTableDefaults"];    


          */  


})();







Screen Shot 2018-02-12 at 12.51.38 PM.png




Screen Shot 2018-02-12 at 12.52.45 PM.png




Screen Shot 2018-02-12 at 12.53.08 PM.png


View solution in original post

8 REPLIES 8

Let me check it


Hey, 

I am not sure if you figured this out. I posted a complete answer with code and images. Please check the accepted answer

Do you have an alternate link or the discussion written down. I have the same issue.


In service portal, angular dependencies should be placed in dependencies as shown images at the bottom. These dependencies are UI scripts with the standard syntax. Updated code as follows.



$scope.$emit("dataReady",c.data.tableData);



The above statement in Widget Client Controller Sends data to dependency/script. $scope.dataset = data.targetScope.data.tableData; in Open Incidents UI script catches it. These are standard angular functions to emit and catch data. Look at angularjs dicumentation for more information https://docs.angularjs.org/api/ng/type/$rootScope.Scope



Widget HTML:



<div   class="container-fluid">


  <br/>


  <div class="panel panel-info">


   


      <div class="panel-body">




          <div class="col-md-12 table table-responsive" -ng-controller="myCtrl">


              <table ng-table="tableParams" class="table table-condensed table-bordered">


                  <tr ng-repeat="row in $data track by $index" >


                      <td data-title="'#'" class="cell"   filter="{ incidentIndex: 'number'}" sortable="'incidentIndex'">{{$index+1}}</td>


                      <td data-title="'Incident Id'" filter="{ incidentId: 'text'}" sortable="'incidentId'"><a href="/haloportal/?id=incident_summary&incident_id={{row.sysId}}" style="color:#0c4a6f"   target="_self">{{row.incidentId}}</a></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>


  </div>


</div>




Widget Client Script:



function($scope)


{


var c=this;


c.getData = function()


{




c.server.get().then(


function(response)


{


c.data.tableData= angular.fromJson(response.data.tableData);


$scope.$emit("dataReady", c.data.tableData);


})


};


c.getData();


}




Widget Server Script:


(function()


{


var json=new global.JSON();


var list=[];


var i=1;


var gr=new GlideRecord('x_19668_halo_incident');


gr.orderByDesc('incident_id');


gr.query();


while(gr.next())


{


list.push({incidentIndex:i++,incidentId:gr.incident_id+'',incidentType:gr.incident_type.name+'',indicatorCount:gr.complted_indicator_count+'',incidentStatus:gr.ticket_status+'',createdDate:gr.sys_created_on+'',lastUpdated:gr.sys_updated_on+'',sysId:gr.sys_id+''});


}



data.tableData=json.encode(list);


})();




Open Incidents UI Script:


(function()


{


"use strict";


      var app=angular.module("openIncidentsModule", ["ngTable"]);



//We are not using this service anymore


app.service('myService',function()


{


//var c=this;


this.getData2=function()


{


var jsonList = JSON.parse(sessionStorage.getItem('jsonListString'));


sessionStorage.removeItem('jsonListString');


return jsonList;


};




});



//Controller


app.controller("myCtrl",["$scope","myService","$rootScope","NgTableParams",function($scope,myService,$rootScope,NgTableParams)


{


var jsonList;


      $rootScope.$on("dataReady", function(data)


{


$scope.dataset = data.targetScope.data.tableData;


$scope.tableParams = new NgTableParams({count:20,sorting:{lastUpdated:"desc"}},{dataset: $scope.dataset,paginationMinBlocks:2,paginationMaxBlocks:13});


}); //End of rootScope



}]);


      /*


angular.module("openIncidentsModule").run(configureDefaults);


function configureDefaults($scope,ngTableDefaults)


{


ngTableDefaults.params.count = 15;


ngTableDefaults.settings.counts = [];


}


configureDefaults.$inject = ["$scope","ngTableDefaults"];    


          */  


})();







Screen Shot 2018-02-12 at 12.51.38 PM.png




Screen Shot 2018-02-12 at 12.52.45 PM.png




Screen Shot 2018-02-12 at 12.53.08 PM.png