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

Hmm darn...



I took the "script" part in the ui page and på it in a UI script and called on it as well, and I guess thats the way I can do it.



Im wondering if I get the same "credentials"-problem if I use the code from the rest api explorer? When I look at the code it give me it doesn't look like the one we're using 😃


Hi Goran,



I did post my question in community but no one replied.. and code u get from rest Api explorer requires u to pass username & password...problem with our app is that we do not know who is using the app..if we will make request with other user credential then it will log them out.



i can think of few solutions..


1)we can store user password in field type 'password(2way)'.. so in our app we can make a call to script include which will fetch username and password(we can decrypt password(2way) field) and set them in $http call.       drawback:servicenow doesnt use password(2way) field by default to store password. it uses password(1way) and it is undecipherable. so somehow we neeed to store all passwords in custom field of password(2way) type.



2)we don't provide any credentials in $http call, let that popup come when they use app for the first time..after we make first REST call..Servicenow will return X-UserToken...we can use that token for sub sequent requests. drawback: user will have to manually enter username and passoword one time, even though they are already using the instance.



Geneva would be much better..in that we can make scripted REST services , and it can be public.


Hmm... Sadly I doubt any of those two solution would work for us




Wouldnt it be possible to instead of a rest call do a   GlideAjax, have it get the objects, make a JSON encode and then in the ui script do a evalJSON to put in the $scope.numbers?



And the retreat suggestion is go back to jelly and do this inside a g2, and the publish it.. .but I don't wanna do jelly


Yeah that can also work. thats better than thinking about this authentication n stuff.



i hope you are aware about this ServiceNow Developers . it shows   how to fetch data in JSON.


Hi,



I need you eyes rossipatel.



I've got the json to work. But somehow the angular repeat won't work. I've been staring at the code for hours now trying everything but It wont show anything.



I've cut down my code to just get the repeat to work but I doesn't want to..



my HTML:



<?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" />




<!-- The User Interface -->


<div ng-app="driftInfo">


  <div ng-controller="mainController" data-ng-init="getAktuellt()">


  <div ng-repeat="num in numbers">


  Tasknumber: {{ num.number }}


  </div>


  outside loop {{ testing }}


  </div>


</div>









</j:jelly>



The "outside loop" with {{ testing }} is working. But that the only thing showing on my screen as "outside loop DARN show yourself!"



The alert in the script part(se below) also works, since it popup every short description that I want..   I just cant understand why the ng-repeat wont work..



Client script:



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




app.controller('mainController', ['$scope', function($scope) {



  $scope.testing = "DARN show yourself!";



  $scope.getAktuellt = function () {



  var ga = new GlideAjax('getDriftinfo');


  ga.addParam('sysparm_name','getActive');


  ga.getXML(showAktuellt);




  };



  function showAktuellt(response) {


  var answer = response.responseXML.documentElement.getAttribute('answer');


  $scope.numbers = angular.fromJson(answer);


  //Just made the for loop to see that I got the correct data


  for (var i=0; i<$scope.numbers.length; i++) {


  alert($scope.numbers[i].short_description);



  }


  }


}]);