Managing records in a UI page using AngularJS and GlideAjax without using REST

ahammoud
Tera Guru

Hello Community,

Lately I have been doing some research on AngularJS and its capabilities in ServiceNow and I find to be very agile and powerful.

I came across alot of interesting topics and noticed alot of developers use REST Api with Angular to manage and manipulate data in a UI Page.

ServiceNow puts an interesting example on how to do it using GlideAjax and AngularJS implicit binding in a UI page:

https://developer.servicenow.com/app.do#!/training/article/app_store_learn_advanced_ui_helsinki_c_Mo...

I find that approach to be very interesting. Based on the example ServiceNow provided I wanted to share some of the scripting I have done on updating the data on the UI Page using GlideAjax without the need of REST API.

In this example I have added a value [u_value] we want to update in the item.

So Basically we are getting a page with a list of records and their input value.

We want the user to be able to update the value of the described item or Add a new one.

Using te angualr COntroller defined in our UI script we will be able to pass on the parameters by GLideAjax to the Server side to update the records on the Server,

I also recommend reading on Jeff's article on using GlideAjax with JSON, his technique uses JQuery:

GlideAjax and JSON | Jeff Benedict

Note: There is no scoping specified here:

UI Page: angular_todo

Direct: de-selected

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

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

<script>

<script>

<script>

<div ng-app="todo">

      <div class="col-md-6" ng-controller="TodoListCtrl" data-ng-init="getNewList()">

                      <h1>Todo List</h1>

  <ul class="list-group">

  <div class="list-group-item" ng-repeat="todoItem in todos">

  {{todoItem.description}}:<br></br><input type="text" id="name" value="{{todoItem.value}}" ng-model="todoItem.value"/>

  </div>

  </ul>

          <!--

  <ul class="list-group">

  <li class="list-group-item" ng-repeat="todoItem in todos" ng-bind="todoItem"></li>

                      </ul>

  -->

  <br></br>

  <button ng-click="modify()" type="button" class="btn btn-primary">Save</button>

                      <div>

                              <label>Add new todo:

                                      <input class="form-control" ng-model="newTodo"/>

                              </label>

  <label>Add new Value:

                                      <input class="form-control" ng-model="newValue"/>

                              </label>

                              <button ng-click="add(newTodo, newValue)" type="button" class="btn btn-primary">Add Todo</button>

                      </div>

              </div>

</div>

</j:jelly>

You also need to specify the UI Scripts:

UI Script: Angular_1_3_framework

document.writeln('<script>https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>');

Your GlideAjax adapter for JSON parsing

UI Script: sn-glideAjax

angular.module('sn.glideAjax', []);

angular.module('sn.glideAjax').service('GlideAjax', function($rootScope) {

  var glideAjax = window.GlideAjax;

  glideAjax.prototype.getJSON = function(callback) {

  this.getXMLAnswer(function(answer) {

  var answerJSON = JSON.parse(answer);

  callback(answerJSON);

  $rootScope.$apply();

  });

  };

  return glideAjax;

});

The main ui script for Angular Controller

UI Script: app_angular_todo

angular.module('todo', ['sn.glideAjax']);

angular.module('todo').controller('TodoListCtrl', function($scope, GlideAjax) {

              $scope.todos = [];

  $scope.getNewList = load();

  //$scope.$apply(load());

  $scope.add = function(newTodo, newValue) {

  $scope.todos.push(newTodo);

  var ga = new GlideAjax('ToDoListItems');

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

  ga.addParam('u_short_description', newTodo);

  ga.addParam('u_value', newValue);

  //ga.setScope(global);

  ga.getJSON(function(response) {

  // don't need to do anything here

  });

      };

  $scope.modify = function() {

  //alert("Here the TOdo Update 4" + JSON.stringify($scope.todos));

  var ga = new GlideAjax('ToDoListItems');

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

  ga.addParam('new_list', JSON.stringify($scope.todos));

  ga.getJSON(function(response) {

  ga.addParam('new_list', response);

  });

      };

  function load() {

  var ga = new GlideAjax('ToDoListItems');

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

  //ga.setScope(global);

  ga.getJSON(function(response) {

  if (!response)

  return;

  $scope.todos = response;

  });

  }

});

FInally getting data back and forth from the server

Script Include: ToDoListItems

Client Callable: True

var ToDoListItems = Class.create();

ToDoListItems.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {

  getList: function() {

  var todos = new GlideRecord('u_x_snc_marketing_ev_to_do_list_item');

  todos.orderBy('u_short_description');

  todos.query();

  var list = [];

  while (todos.next()) {

  var listo = {};

  listo.description = todos.u_short_description.toString();

  listo.value = todos.u_value.toString();

  listo.sysid = todos.sys_id.toString();

  list.push(listo);

              }

  return new global.JSON().encodeArray(list);

      },

  modify: function() {

  var newStuff = this.getParameter('new_list');

  var recordObj = new JSON().decode(newStuff);

  var todos = new GlideRecord('u_x_snc_marketing_ev_to_do_list_item');

  todos.query();

  while (todos.next()){

  //since we are dealing with an object we need to get its String value to validate in our GLideRecord

  for ( var x=0; x < recordObj.length; x++ ){

  var osysID = JSON.stringify(recordObj[x].sysid);

  if (todos.sys_id == JSON.parse(osysID)){

  var cleanValue = JSON.stringify(recordObj[x].value);

  todos.u_value = JSON.parse(cleanValue);

  todos.update();

  }

  }

  }

  gs.addInfoMessage("Properties Updated");

  },

  add: function() {

  var todos = new GlideRecord('u_x_snc_marketing_ev_to_do_list_item');

  todos.newRecord();

  todos.u_short_description = this.getParameter('u_short_description');

  todos.u_value = this.getParameter('u_value');

  todos.insert();

  },

  type: 'ToDoListItems'

});

Thank you,

Hope this is helpful,

1 REPLY 1

Goran WitchDoc
ServiceNow Employee
ServiceNow Employee

Great work, just a thought. If you going to do Angular and want a specific page. Use the Service Portal if possible. For example take a look how they did with the CAB Workbench... Then you can use the whole "widget" thingie and skip the GlideAjax etc. as well.



//Göran