how to get records with angularJS

Goran WitchDoc
ServiceNow Employee
ServiceNow Employee

Hi,

Just to clear out the conditions 😃 I'm pretty new to servicenow and developing. Coding has always been there in the background all life, but it has never been my main work.

I'm trying to learn how to get angularJS to work like I want and I've been through a lot of tutorials of AngularJS but I havnt found anyone that covers really how to get the information from ServiceNow. all these always put the data in the controller manually.

And when it comes to REST, Im totally new 😃

I've played around abit with the info from Angular in ServiceNow: Tutorial #3 - REST Calls-John Andersen

and I get it to work. But since that one requires a input for the tickets to show, I want to know how to make a ui page that shows the records without any manually input calling for the function to get it.. but show all the records that my query is. Im trying this out on my personal dev-instance.

In my dream world I would just take away the function part and use the get right up, but I guess Im missing something.

This is what I got.

UI page:

<?xml version="1.0" encoding="utf-8" ?>

<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">

  <!-- Import AngularJS Library -->

  <g:requires name="angular.min.jsdbx" />  

  <!-- Import my UI Script - get updated timestamp to invalidate cache if script changes -->

  <g2:evaluate var="jvar_stamp">

      var gr = new GlideRecord('sys_ui_script');  

      gr.get("e608a7e94fc41600028f7ab28110c748");

      gr.getValue('sys_updated_on');

  </g2:evaluate>  

  <g:requires name="driftinformation.jsdbx" params="cache=$[jvar_stamp]" />  

  <!-- The User Interface -->

  <div ng-app="descEditor" style='padding:40px;'>

      <div ng-controller="DescriptionText">

          <table><tr>

<!--               <td style='width: 300px; vertical-align: top;'>

                  <p>NUMBER</p>

                  <input ng-model="incnum" ng-change="updateRecordList(incnum);"/>

              </td> -->

              <td style='vertical-align: top; padding: 20px;

                                                                        background-color: #B2B2B2; width: 200px;'>

                  <div ng-repeat="num in numbers">{{num.number}}</div>

              </td>

          </tr></table>

      </div>

  </div>

</j:jelly>

UI Script:

var myApp = angular.module('descEditor', []);

myApp.controller('DescriptionText', [

  '$scope',

  '$http',

  function($scope, $http) {

      $scope.incnum = "INC010";

      $scope.url = '/api/now/table/incident';

      $http.defaults.headers.common.Accept = "application/json";

     

      $http({

              method: 'GET',

              url: $scope.url + "?sysparm_query=numberSTARTSWITH"+incnum+

                                                  "^ORDERBYDESCnumber"+

                                                  "&sysparm_fields=number&sysparm_limit=25",

          }).

          success( function(data, status) {

              $scope.numbers = data.result;

          }).

          error ( function(data, status) {

              $scope.numbers = [{"number": "Error fetching list"}];

          });

     

  }

] );

I'm hoping someone in the community can point me in the right direction 😃

1 ACCEPTED SOLUTION

Rushit Patel2
Tera Guru

Hi Göran Lundqvist,



Great to see many pepl trying Angular on Service now. to execute any function on Load u need to use this attribute 'data-ng-init'.



so HTML side looks like this



<div ng-controller="DescriptionText" data-ng-init="getAllActive()">



And your Controller would look like this. add that method.


$scope.getAllActive = function(){


        $http({


                method: 'GET',


                url: $scope.url + "?sysparm_query=active=true",


            }).


            success( function(data, status) {


            $scope.numbers = data.result;


            }).


            error ( function(data, status) {


                $scope.numbers= [{"number": "Error fetching list"}];


            });


      };


   



it will show all Active Incidents.



I Hope it WOrks for u.



***mark helpful/like/correct based on impact of reply*****




Regards,


Rushit Patel




View solution in original post

49 REPLIES 49

Hi Goran,



ahhh....I see the problem. when u are making rest calls to servicenow REST api's u must include basic Authentication or 'X-UserToken' header with correct token.



so in below code I have included basic authentication. username and password must b encoded so I have included dependency from ninjatronic/angular-base64 · GitHub .



see below code



angular.module('todoService',['base64'])


.factory('getList', function($http,$base64){
var listFactory = {};




var username = 'username';
var password = 'password';
var authdata = $base64.encode(username + ':' + password);

  listFactory.getinc = function(){
 
  return $http.get('https://yourincstace.service-now.com/api/now/table/incident?sysparm_query=active%3Dtrue&sysparm_fiel...',{
    headers: {
      'Authorization' : 'Basic ' + authdata
      }


 
});

return listFactory;
};


});



I hope it helps.



regards,


Rushit Patel


Hmm.. I thought I understood it 😃



but I got an error on the URL. Right now Im using admin, but I thought I just do that so I know it isnt any credentials messing around to get it to work. How do you do it otherwise since I guess you dont have admin to do this. Do I create a certain user to use to do the REST-calls?



I also have put down the angular-base64 as a ui script and calls on it with "


<g:requires name="angular-base64.min.jsdbx" />"




var myApp = angular.module('descEditor', ['base64']);




myApp.controller('DescriptionText', [


  '$scope',


  '$http',


  function($scope, $http, $base64) {


      $scope.url = '/api/now/table/u_driftinfo';


      $http.defaults.headers.common.Accept = "application/json";


  var username = 'admin';


var password = 'xxxxxxxxx';


var authdata = $base64.encode(username + ':' + password);


   


   


      $scope.getAllActive = function() {



  $http({


              method: 'GET',


              url: $scope.url + "?sysparm_query=u_valid_to>=javascript:gs.daysAgoEnd(0)^ORu_valid_toISEMPTY",{


  headers: { 'Authorization' : 'Basic ' + authdata }}


          }).


          success( function(data, status) {


              $scope.numbers = data.result;


          }).


          error ( function(data, status) {


              $scope.numbers = [{"number": "Error fetching list"}];


          });


  }  


  $scope.getAllHistory = function() {


 


  }


] );


Hi Goran,


don't forget to add $base64 as shown below.




myApp.controller('DescriptionText', [


  '$scope',


  '$http','$base64',


  function($scope, $http, $base64) {



and try making simple rest calls without those complicated Query params.



now coming to the Making REST calls with which user? is complicated and pain in rear for me. I never made anything for end user so i always used admin credentials.   now if u make any user specifically to make rest calls for all users of that app,it will make REST calls but when u navigate away from your UI page and try to open any other record, instance will automatically Log out the User and log in the user u set in REST call. This is Super Wierd. I don't know how people handle this in SNOW. may b someone from community can help.


Well.. this one Im going to use to publish information on our portal, without demanding a login. I doing this as a UI page on my personal dev since I didnt wanna spend time to set up a portal there. I figured that if I got it to work in a ui page, I could take that xml-code and put it in a dynamic context block and it would work there as well. Am I on the wrong way here? 😃



What we are using this for is that we have Service status(I think its called in english). So we can put up outages, pure information, planned service etc. for the end customers.



Dont know if the auth.. stuff will change if I put in in the portal thou, but since the rest-call is made from a ui script I dont think so or?


Hi Goran,



yes if you put your code into into dynamic content blocks it will definitely work however u can not use embedded scripts in that. but problem of making REST calls still persists. so if you make REST calls using admin credentials in script. and now any user comes to portal n when they will come to your dynamic block and if they navigate somewhere else ,their session will automatically end and admin will be automatically logged in.



Let me post question in community.