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 code
    var 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 number 10.

    Copy code
    if (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 code
    if (Bug_Fields)("BG_BUG_ID").Value === '10'

Back to top

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:

Copy code
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
}

Back to top

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:

Copy code
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);
    }
}

Back to top

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:

Copy code
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.
}

Back to top

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.

Copy code
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.
  }
  
}

Back to top

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.

Back to top

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.

Copy code
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.

Copy code
function Bug_New()  {
    return MsgBox('Show this message before new dialog').then(function() {
    Bug_Fields("BG_ACTUAL_FIX_TIME").Value = 50;
});
}
Copy code
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.

Back to top

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.

Back to top