Best practices for writing workflow scripts
This section describes best practices for writing workflow scripts and making sure the scripts run as expected.
Check value types before use
Values of different types behave differently in different statements. To avoid unpredictable results, check value types before you use the values.
-
Check the value type is you are not sure.
For example, to check the value type of the Defect ID field (BG_BUG_ID):
Copy codevar valuetype = typeof Bug_Fields("BG_BUG_ID").Value;
//Print it in console or show message dialog directly
console.log(valuetype);
//MesgBox(valuetype) -
Use loose equality (==) if you do not want to check between string and number.
For example, the following statement is run when the value is the string
10
or the number10
.Copy codeif (Bug_Fields)("BG_BUG_ID").Value == 10
-
Use strict equality (===) if you are clear about the value type
For example, the following statement is run only when the value is the string
10
.Copy codeif (Bug_Fields)("BG_BUG_ID").Value === '10'
Check if a value is empty
To avoid errors, check that all values are not empty before attempting to use them.
For example, suppose the value of the custom user field BG_USER_01 is an array, to check if the value is empty, use the following:
var userField = Bug_Fields("BG_USER_01");
var value = userField.Value;
var isMultiple = userField.IsMultiValue;
if (isMultiple && Array.isArray(value)) && value.length > 0) {
//Execute something
}
Convert date strings to date objects before comparison
Various date string formats are accepted as long as they are valid. If you want to compare dates, we recommend you first switch each date string to a Date object, and then compare these date objects.
For example, suppose you want to define that if a bug's detection date is earlier than a specific date, a message box pops up, you can write the following scripts:
function Bug_MoveTo() {
var detectionDate = new Date(Bug_Fields("BG_DETECTION_DATE").Value);
var toComparedDate = new Date('2023/12/12');
if (detectionDate < toComparedDate) {
MsgBox(Bug_Fields("BG_BUG_ID").Value);
}
}
Add break statements for switch and provide default action
If you use switch
statements to perform different actions based on different conditions, make sure you also add break
statements and a default
clause.
-
break statement. The
break
after switch case s is used to avoid the fallthrough in the switch statements. -
default clause. If there is no match, the code block in the default clause is executed.
For example:
functionBug_FieldChange(fieldName) {
var StatusFieldName = 'BG_STATUS';
if (fieldName == StatusFeildName) {
var value = Bug_Fields(StatusFieldName).Value;
switch (value) {
case 'New':
// add code block to define what to execute if the status is changed to New.
break;
case 'Open'
// // add code block to define what to execute if the status is changed to Open.
break;
default:
// // add code block to define what to execute if there is no match.
break
}
return;
}
// add code block to define what to execute if the changed field is not Status.
}
Distinguish between new entity and entity details dialog boxes
Before adding workflow scripts to an event, confirm if the event is triggered when a user create an entity or opens an entity.
In the following example, the Bug_FieldChange event is triggered when a user creates a defect.
function Bug_FieldChange(fieldName) {
if (ActiveDialogName === 'New Bug') {
//add code to define what to execute when a user creates a defect.
} else {
//add code to define what to execute when a user edits a defect.
}
}
Avoid defining duplicate variables or functions
If you define a variable or function in one section and then add another variable or function with the same name in another section, then conflicts occur. One of variable or function is not executed.
To avoid unpredictable conflicts when defining variables or functions, always check if another variable or function with the same name already exists in your project.
About the use of message box
When you use the MsgBox function to pop up a message box, it does not block the execution of the remaining operations. If you want to block the operations until a user interaction is performed in the message box, you can use promises or await/async.
Note: MsgBox is not applicable to advanced project scripts.
For example, if you customize the Bug_New event as follows without using promises or await/async, the message box and then New Defect dialog box opens at the same time when a users creates a defect.
function Bug_New() {
MsgBox('Show this message');
Bug_Fields("BG_ACTUAL_FIX_TIME").Value = 50;
}
If you use a promise or await/async as follows, when a user creates a defect, the message box pops up, and only when the user clicks OK in the message box, the New Defect dialog box appears.
function Bug_New() {
return MsgBox('Show this message before new dialog').then(function() {
Bug_Fields("BG_ACTUAL_FIX_TIME").Value = 50;
});
}
async function Bug_New() {
await MsgBox('Show this message before new dialog');
Bug_Fields("BG_ACTUAL_FIX_TIME").Value = 50;
}
Note: Await/async has a higher requirement for your browser version. Before you use await/async, check if it is supported by your browser.
Set log level to debug for troubleshooting
Applicable to: Advanced project scripts.
To help with troubleshooting when executing advanced project scripts, set the log level to debug, which records events that are most useful for debugging.
For details about setting log level, see Configure ALM server log file settings.