Issue in UI Macro using angular js

Sindhuja10
Kilo Expert

I created a UI Macro using angular js where the functionality is working on the form. After submitting the RITM getting error - Uncaught Error: [ng:btstrpd]

9 REPLIES 9

Hi sindhujab,

Acutally in the html markup first line, using "ng-app=" is bootstrapping the module. However, ServiceNow uses the angular.bootstrap(element); method to initialize AngularJS. Per the AngularJS documentation it isn't recommended to use both in the same app.

I believe if you change ng-app="MyApp" to the id attribute like this: id="MyApp". Also in order for the controller to work when viewed in the RITM this attribute needs to be added to the same top element sn-ng-formatter="MyApp". 

ie: <div id="MyApp" sn-ng-formatter="MyApp" ng-controller="MyController">

 Then add the following line at the end of your script to bootstrap the module:

angular.bootstrap(document.getElementById('MyApp'), ['MyApp']);

If the RITM still gives an error for the controller you may have to require the angularjs library with something like this at the top of the macro:

<g:requires name="scripts/angular_1.5.11/angular.min.js" includes="true"/>

Here are some reference posts:

https://community.servicenow.com/community?id=community_question&sys_id=24c6cf65db1cdbc01dcaf3231f96195c&view_source=searchResult

https://community.servicenow.com/community?id=community_question&sys_id=325247eddb98dbc01dcaf3231f9619d1

Hi Chris,

I modified the above code as you said like,

angular.element(document).ready(function() {
angular.bootstrap(document, ['MyApp']);
});
angular.module('MyApp', [])
.controller('MyController', function ($scope, $window){

});

Previously i got Uncaught Error: [ng:areq] and Uncaught Error: [ng:btstrpd] errors. Still I am getting Uncaught Error: [ng:btstrpd] error. Is there anything I am missing?

Thanks in advance

That's not quite what I suggested. I didn't wrap mine in the document.ready. I suggested to add angular.bootstrap(document.getElementById('MyApp'), ['MyApp']) at the end of your already existing script.

 

<!-- possibly may need this next line 
<g:requires name="scripts/angular_1.5.11/angular.min.js" includes="true"/>
-->

<div id="MyApp" sn-ng-formatter="MyApp" ng-controller="MyController">
    <div class="table-responsive">
       <table cellpadding="0" cellspacing="0">
        <tr>
         <th>Owner</th>
         <th>Group</th>
        </tr>
        <tbody ng-repeat="m in Storages">
          <tr>
           <td><input class="form-control" value="{{m.owner}}"/></td>
           <td><input class="form-control" value="{{m.group}}"/></td>
           <td><input type="button" ng-click="Remove($index)" value="Remove" /></td>
          </tr>
        </tbody>
        <tfoot>
          <tr>
           <td>
             <input class="form-control" 
                    type="text" 
                    id="owner" 
                    ng-model="owner" 
                    maxlength="20"/>
           </td>
           <td>
             <input class="form-control" 
                    type="text" 
                    id="group" 
                    ng-model="group" 
                    maxlength="50" />
           </td>
           <td>
             <input type="button" id="Add" ng-click="Add()" value="Add" />
           </td>
          </tr>
        </tfoot>
       </table>
    </div>
 </div>

<script>
angular.module('MyApp', [])
  .controller('MyController', function ($scope, $window) {
     $scope.Storages = [];
     $scope.Add = function () {
        var fieldValues = [$scope.owner, $scope.group];
        var values = {"owner":fieldValues[0],"group":fieldValues[1]};
        $scope.Storages.push(values);
 
       //Clear the TextBoxes.
       $scope.owner = "";
       $scope.group = "";
     };

     $scope.Remove = function (index) {
 
        if ($window.confirm("Do you want to delete this record?")) {
 
        //Remove the item from Array using Index.
        $scope.Storages.splice(index, 1);
 
        }
     };
 });
angular.bootstrap(document.getElementById('MyApp'), ['MyApp']);
</script>

Omkar Mone
Mega Sage

Hi 

UI Macros and UI pages are based on Jelly... Service Portal is a Jelly free environment and as such Ui Macros and Ui Pages will not render in the Service Portal. This is by design. Jelly is also a server side template, so I'm not even sure how it would work to have this display in a client side single page app such as Service Portal.

 

The alternative Service Portal provides is the ability to render a widget inside the catalog variable. If you look through the variable form, you should notice a widget field.

 

 

Hi,

I am creating both UI Macro and a widget so that it would work in Service Portal