Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Problem calling a Script Include from a Business Rule

Katie A
Mega Guru

I am making a scoped application in Fuji. I having a problem when I try to call a Script Include from a Business rule. I have confirmed that all of the artifacts such as the script include and business rule are all residing in the same application scope.

I should be able to call the script include as such:


var x = new MyScript();

x.myFunction();

The business rule:


function onBefore(current, previous){

var lu = new LoanerResUtils();

lu.isAvailable();

}

This is not working and I see the undefined error in the log.

The script include name is LoanerResUtils.

org.mozilla.javascript.EcmaError: The undefined value has no properties.

Caused by error in Business Rule: 'Loaner Res Item Availability' at line 20

==> 20: var lu = new LoanerResUtils();

21: lu.isAvailable();

I tried using the fully-qualified scope name but that did not work either.

org.mozilla.javascript.EcmaError: "x_myscp_loaner_res_LoanerResUtils" is not defined.

Caused by error in Business Rule: 'Loaner Res Item Availability' at line 20

==> 20: var lu = new x_myscp_loaner_res_LoanerResUtils();

21: lu.isAvailable();

This exact syntax has worked for me in Eureka so I am not sure what could be the issue here.

Let me know if anyone has any possible solutions!

Here is the script include.

Screen Shot 2015-08-17 at 4.11.29 PM.png

1 ACCEPTED SOLUTION

coryseering
ServiceNow Employee
ServiceNow Employee

Hi Kathryn,



Do you have an initialize method in your Script Include? You need one for the Prototype class-extension.



var LoanerResUtils = Class.create();


LoanerResUtils.prototype = {


      //THIS IS REQUIRED


      initialize: function() {


      },


     


      //ALL YOUR METHODS DEFINED LIKE THIS


      isAvailable : function() {


              //whatever logic


      },


     


      //THIS IS ALSO REQUIRED


      type: 'LoanerResUtils'


};



If you go the Class extension route (the default for Script Includes) you need to have an initialize method (even if it's empty) and a type declaration.


View solution in original post

14 REPLIES 14

Thanks again for jumping in so quickly. There was an error and it looks like there is an issue with the global script "PrototypeServer". That is an OOTB script and it has not been modified. According to the error message it may be causing the issue with my script include. Let me know what you think and thank you very much.




Evaluator: org.mozilla.javascript.EcmaError: The undefined value has no properties.


  Caused by error in Script Include: 'PrototypeServer' at line 4



  1: var Class = {


  2: create: function() {


  3: return function() {


==> 4: this.initialize.apply(this, arguments);


  5: }


  6: }


  7: }



Evaluator: org.mozilla.javascript.EcmaError: The undefined value has no properties.


  Caused by error in script at line 1



==> 1: var lu = new LoanerResUtils();


  2: gs.info("Type of LRU: " + typeof lu);


  3: gs.info(lu.isAvailable);



Evaluator: org.mozilla.javascript.EcmaError: The undefined value has no properties.


  Caused by error in script at line -1






coryseering
ServiceNow Employee
ServiceNow Employee

Hi Kathryn,



Do you have an initialize method in your Script Include? You need one for the Prototype class-extension.



var LoanerResUtils = Class.create();


LoanerResUtils.prototype = {


      //THIS IS REQUIRED


      initialize: function() {


      },


     


      //ALL YOUR METHODS DEFINED LIKE THIS


      isAvailable : function() {


              //whatever logic


      },


     


      //THIS IS ALSO REQUIRED


      type: 'LoanerResUtils'


};



If you go the Class extension route (the default for Script Includes) you need to have an initialize method (even if it's empty) and a type declaration.


Yes the first one is initialize. Here is the entire Script Include.



var LoanerResUtils = Class.create();



LoanerResUtils.prototype = {


  initialize: function() {


      },


  isAvailable : function(ci, start, end) {



      var ci_id = ci;


      var count = 0;


  var lr = new GlideAggregate('x_broi2_loaner_res_loaner_reservation');




  if (ci instanceof GlideRecord)


          ci_id = ci.sys_id;



      var myQuery = 'active=true^';


      myQuery += 'cmdb_ci.sys_id=' + ci + '^';


      myQuery += 'x_broi2_loaner_res_start_date<=' + end + '^';


      myQuery += 'x_broi2_loaner_res_end_date>=' + start + '^';


      myQuery += 'NQ';


      myQuery += 'active=true^';


      myQuery += 'cmdb_ci.sys_id=' + ci + '^';


      myQuery += 'x_broi2_loaner_res_end_date<=' + gs.daysAgo(0);



      lr.addEncodedQuery(myQuery);


      lr.addAggregate('COUNT');


      lr.query();


      if (lr.next()) {


          count = lr.getAggregate('COUNT');


  gs.info("Count lr " + count + " sys_id " + ci_id);


  if (count == 0) {


  var answer = 'true';


  }


  else if (count > 0) {


  var answer = 'false';


  }


      }


  return answer;



  },



  availableCis : function(class_name, pickup_location, start, end) {


      var ci                                       = new GlideRecord('cmdb_ci');


      var availableItems               = [];


      ci.addQuery('loaner', true);


      ci.addQuery('sys_class_name', class_name);


      ci.addQuery('depot', pickup_location);


      ci.query();




      while (ci.next()) {


          var id = ci.sys_id.toString();


  gs.info("Ci sys_id: " + id);


  var lnrUtil = new LoanerResUtils;




  gs.info("Count available: " + id + lnrUtil.isAvailable(id, start, end));



  if (lnrUtil.isAvailable(id, start, end) == 'true'){


                  availableItems.push(id);


  }


      }


  gs.info("Avail Items: " + availableItems.join(','));


      return availableItems.join(',');


  },




  type: 'LoanerResUtils'


}


coryseering
ServiceNow Employee
ServiceNow Employee

Hi Kathryn,



That include works for me. Well, it's available in my context as I expect. Obviously the individual methods don't work, since I don't have your custom table. Also, it looks like there is a minor bug on line 54 (no parens invoking the constructor). But otherwise it exists where I expect.



Mind if I give you call to discuss?


I can get your contact info from Hi.


Sure that would be great.