- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-22-2024 10:25 AM
Hello,
I have a Business Rule created on a custom table configured to trigger off of two conditions:
1. Field 'u_status' is 'Refresh'
or
2. Field 'u_last_webhook_dt' changes
Condition 1 is triggered from a UI Action button labeled 'Refresh', while Condition 2 is triggered from a Scripted REST API script.
When triggering using the 'Refresh' UI Action the Business Rule errors when attempting to instantiate my global script include; however, when triggering from the Scripted REST API or from a background script the Business Rule instantiates the object successfully and completes without error.
Ultimately, my question is: why am I getting the `[object Object] is not a function` error when instantiating the Script Include through the UI Action, but not getting the error when using the Scripted REST API or background script?
Things I have verified:
- All scripts are in `Global` scope
- 'Isolate Script' is turned off for all relevant scripts
- Verified the user clicking the UI Action has all necessary roles
The Business Rule code and error thrown are shown below:
try {
var DealHubCPQHelper = new global.DealHubCPQHelper( ), // <-- ERROR THROWN HERE
quotedetails = DealHubCPQHelper.getDealHubQuoteDetails( current ),
nil;
} catch ( err ) {
err.func = "Business Rule: DealHub API Get Quote Details";
gs.error( [ err.message, JSON.stringify( err ) ].join( ), "DealHubCPQ" );
}
Error Message:
[object Object] is not a function.,
{"message":"[object Object] is not a function.","fileName":"sys_script.609271651b0d42509c9b0e12604bcb93.script","sourceName":"sys_script.609271651b0d42509c9b0e12604bcb93.script","lineNumber":9,"name":"TypeError","stack":"\tat sys_script.609271651b0d42509c9b0e12604bcb93.script:9 (executeRule)\n\tat sys_script.609271651b0d42509c9b0e12604bcb93.script:40\n\tat sys_script_include.00087ee91b74c61062638556cc4bcbc4.script:333 (cleanseGlideRecord)\n\tat sys_script_include.00087ee91b74c61062638556cc4bcbc4.script:307\n\tat sys_ui_action.c3b9e62d1bcd42509c9b0e12604bcb75.script:24\n","rhinoException":{},"func":"Business Rule: DealHub API Get Quote Details"}
So, starting from the bottom of the stack, we see the 'sys_ui_action' execute, followed by the script call within the UI Action to 'cleanseGlideRecord' which completes successfully and provides the record `.update()` function which triggers the Business Rule 'DealHub API Get Quote Details' to execute.
The UI Action script is as follows:
function getQuoteDetails ( ) {
var answer = confirm( "Are you sure you want to refresh details using the DealHub API Engine?\n\nThis will clear, retrieve, and parse new quote data from DealHub for the selected record(s)."),
nil;
// Interact with the form button using g_form to allow use of confirm dialog
if ( answer == true )
gsftSubmit( null, g_form.getFormElement( ), 'dealhub_get_detail' );
else
return false;
}
try {
if ( typeof window == "undefined" ) {
current.setValue( "u_status", "Refresh" );
var DealHubCPQHelper = new global.DealHubCPQHelper( ),
GrDealHubCPQQuote = DealHubCPQHelper.cleanseQuoteDetails( null, current ),
nil;
action.setRedirectURL( current );
}
} catch ( err ) {
err.func = "UI Action.Refresh";
gs.error( JSON.stringify( [ err, err.message ].join( ) ), "DealHubCPQ" );
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-25-2024 05:46 PM - edited 03-25-2024 05:48 PM
Hi All,
After some more troubleshooting I was able to resolve the problem. The solution is still somewhat perplexing as it points to some strange unknown behavior with UI Actions calling Script Includes that update records and then initiate Business Rules.
Ultimately, my UI Action was performing a `.setValue( ... )`, calling a global Script Include to `.setValue( ... )` and `.update( )`. Which then triggers a Business Rule to perform another `.setValue( ... )` and `.update( )` operation.
So, I eliminated the call to the Script Include (DealHubCPQQuote.cleanseQuoteDetails) within the UI Action and now the UI Action is simply doing the following:
Refresh UI Action
...
if ( typeof window == "undefined" ) {
current.setValue('u_status', 'Refresh');
current.update( );
action.setRedirectURL( current );
}
I mentioned in the original post :
@Corey Farmer wrote:"...we see the 'sys_ui_action' execute, followed by the script call within the UI Action to 'cleanseGlideRecord' [cleanseQuoteDetails] which completes successfully and provides the record `.update()` function which triggers the Business Rule 'DealHub API Get Quote Details' to execute."
So, the Business Rule now calls what the UI Action was calling (DealHubCPQQuote.cleanseQuoteDetails). Allowing the BR to shoulder most of the operational weight. From a process flow perspective, this works better too - cleansing the record details just before the call to get new details.
onBefore Business Rule
var DealHubCPQHelper = new global.DealHubCPQHelper( ),
GrDealHubCPQQuote = DealHubCPQHelper.cleanseDealHubQuoteDetails( null, current ),
quotedetails = DealHubCPQHelper.getDealHubQuoteDetails( current ),
nil;
...
DealHubCPQQuote.CleanseQuoteDetails
cleanseQuoteDetails : function ( Gr ) {
if ( Gr.isValidRecord ( ) ) {
Gr.setValue( "u_event_info", "" );
Gr.setValue( "u_quote_info", "" );
Gr.setValue( "u_quote_additional_data", "" );
Gr.setValue( "u_quote_summary", "" );
Gr.setValue( "u_quote_line_items", "" );
Gr.setValue( "u_quote_answers", "" );
Gr.setValue( "u_quote_approval_details", "" );
Gr.setValue( "u_error_message", "" );
}
}
So, it would seem that the Business Rule acts differently when the UI Action calls a Script Include to perform an update, versus making the update within its own body? Clearly, the UI Action is still issuing an initiating trigger for the Business Rule to execute, the only difference now is calling the Script Include within the UI Action..... strange, but it solves the issue.
A big thank you for everyone's help!

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-25-2024 11:12 AM
I dont know if it is a silly question or you already have it corrected, but why do you have comma after each line instead of ;
try {
var DealHubCPQHelper = new global.DealHubCPQHelper( ), // <-- ERROR THROWN HERE
quotedetails = DealHubCPQHelper.getDealHubQuoteDetails( current ),
nil;
Please mark this response as correct or helpful if it assisted you with your question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-25-2024 12:09 PM
Hi, not a silly question - just programming preference I suppose. The `var` for variable instantiation works by chaining as well, so it doesn't need to be called for each variable if you don't want to (Javascript trick).
var myVar1 = "value1";
var myVar2 = "value2";
// Is the same as:
var myVar1 = "value1", myVar2 = "value2";
// Is the same as:
var myVar1 = "value1",
myVar2 = "value2";
Arguably, there may be performance gains from not calling `var` so often; but, I've never done the analysis and it's likely too minute to impact execution time at all - so, "just programming preference I suppose."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-22-2024 10:41 AM
Hi Corey,
Is DealHubCPQHelper a script include?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-22-2024 11:03 AM
Hi @Neel Patel ,
Thank you for your contribution!
Yes, `DealHubCPQHelper` is a Script Include within the Global scope (the Scripted REST API, Business Rule, and UI Action are also within Global), with Accessibility set to "All application scopes", and Protection Policy is "None"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-22-2024 04:06 PM
Just a thought, can you try this: (Invoking function with the SC object)
var my_sc = DealHubCPQHelper.getDealHubQuoteDetails(param);