Jazz Forum Welcome to the Jazz Community Forum Connect and collaborate with IBM Engineering experts and users

Is dojo.xhrGet supported in calculated value scripts?

Question:
Can I use dojo.xhrGet in a custom script of calculated values to fetch timeline details?

Environment:
EWM 7.0.2
Application: Work Items -> Attribute Customization -> Script-based Value Provider

This is my xhrGet code :-
var xhrGet = dojo.xhrGet({
    url: projectTimeline,
    handleAs: "xml",
    sync: true,
    load: function(response) {
        var xmlDoc = response.documentElement;
        var timelines = xmlDoc.getElementsByTagName("values");

        for (var i = 0; i < timelines.length; i++) {
            var iterations = timelines[i].getElementsByTagName("iterations");
            for (var j = 0; j < iterations.length; j++) {
                var id = iterations[j].getElementsByTagName("id")[0].textContent;
                if (id === Iteration) {
                    var timelineLabel = timelines[i].getElementsByTagName("label")[0].textContent;
                    console.log("Timeline Label:", timelineLabel);
                    return;
                }
            }
        }
    },
    error: function(error) {
        console.error("Error fetching XML:", error);
    }
});

Error in ccm.log:-
Error invoking value provider 'CustomURLProvider' associated with the attribute 'Link' in the project area with id '<projectAreaId>'.
You can link to the project area definition using a URL similar to
https://<hostname>:9443/jazz/process/project-areas/
<projectAreaId>,
where the host name, port and jazz context are configured for your installation.
Contact your project area administrator for assistance.

" com.ibm.team.rtc.common.scriptengine.UnknownTypeException: '<custom.class.name>' is not a constructor
    at com.ibm.team.rtc.common.scriptengine.environment.ScriptingHelperImplementation.getConstructor(ScriptingHelperImplementation.java:162) ~[?:?]
    at com.ibm.team.rtc.common.scriptengine.ScriptUtilities$1.run(ScriptUtilities.java:30) ~[?:?]
    at com.ibm.team.rtc.common.scriptengine.environment.AbstractScriptEnvironment.execute(AbstractScriptEnvironment.java:74) ~[?:?]


If I remove/comment the xhrGet part, the script runs without errors.

->Is dojo.xhrGet actually supported in calculated value scripts, or is there another supported way to fetch timeline/iteration details from the server?

0 votes



3 answers

Permanent link
You are better off using the jazzclient version, which will do session management as well:

dojo.require("jazz.client");

  (function() {
    const jazzClient = jazz.client;

      const xhrArgs = {
        url,
        headers  : { 'Accept' : 'application/json' },
        handleAs : 'json'
      };

      jazzClient.xhrGet(xhrArgs).then(response => {}

1 vote


Permanent link
dojo.xhrGet and other network requests like dojo.xhrPost are generally not supported within calculated value scripts in environments like IBM Rational Team Concert (RTC).

The primary reason for this limitation is that calculated value scripts are typically executed within a context that does not allow for external network requests due to security restrictions and the synchronous nature often expected of calculated values. Attempting to use dojo.xhrGet in such a script will likely result in an error indicating that the function cannot be found or executed in that specific object context, as the necessary network request capabilities are not exposed or permitted.

1 vote


Permanent link
Hello Davyd Norris
Thanks for the response - but in RTC  dojo.xhrGet (or any network request) is not supported in Calculated Value

Here is my entire code and your suggestion too throws the similar error.

Cannot find function xhrGet in object [object Object]
dojo.provide("com.URLGenerator");
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");

(function() {
    dojo.declare("com.URLGenerator", null, {

        getValue: function(attribute, workItem, configuration) {
            var WorkItemAttributes = com.ibm.team.workitem.api.common.WorkItemAttributes;
            var customWorkItemAttributeTool = workItem.getLabel('com.rtc.configuration.workitemtype.customattribute.tool');
            var workflowType = workItem.getValue(WorkItemAttributes.TYPE);
            var workflowState = workItem.getValue(WorkItemAttributes.STATE);
            var Iteration = workItem.getValue(WorkItemAttributes.PLANNED_FOR);
            var category = workItem.getLabel(WorkItemAttributes.FILED_AGAINST);
            var workitemid = workItem.getValue(WorkItemAttributes.ID);
            var result = "";
            var timelineLabel = "Unassigned";
            if (!workflowState || customWorkItemAttributeTool === "Unassigned") {
                result = "";
            } else {
                category = category ? category.replace(/[^A-Z0-9]/ig, " ").replace(/\s+/g, "") : "Unassigned";

                var serverKey = "serverKey";
                if (configuration && configuration["serverKey"]) {
                    serverKey = configuration["serverKey"];
                }

                var ProjectArea = workItem.getValue(WorkItemAttributes.PROJECT_AREA);
                var projectTimeline = "https://alm-ccm-server/ccm/service/com.ibm.team.workitem.common.internal.rest.IWorkItemRestService/timelinesWithIterations?projectAreaItemId=" + ProjectArea + "&includeArchived=false&requireDeliverable=false";                
                try {
                    var xhrGet = dojo.xhrGet({
                        url: projectTimeline,
                        handleAs: "xml",
                        sync: true,
                        load: function(response) {
                            console.info('response', response);
                            var xmlDoc = response.documentElement;

                            var timelines = xmlDoc.getElementsByTagName("values");

                            for (var i = 0; i < timelines.length; i++) {
                                var timeline = timelines[i];
                                var iterations = timeline.getElementsByTagName("iterations");

                                for (var j = 0; j < iterations.length; j++) {
                                    var iteration = iterations[j];
                                    var id = iteration.getElementsByTagName("id")[0].textContent;

                                    if (id === Iteration) {
                                        timelineLabel = timeline.getElementsByTagName("label")[0].textContent;
                                        console.log("Timeline Label-2:", timelineLabel);
                                    }
                                }
                            }

                            if (!timelineLabel) {
                                console.log("Timeline not found for Iteration:", Iteration);
                                timelineLabel = "Unassigned";
                            }
                        },
                        error: function(error) {
                            console.error('Error occurred while fetching XML:', error);
                        }
                    });

                    timelineLabel = timelineLabel.replace(/[^A-Z0-9]/ig, " ").replace(/\s+/g, '
');
                    result = "targetBaseURL" +
                        "/" + workitemid +
                        "/" + timelineLabel +
                        "/" + category +
                        "/" + serverKey +
                        "/0";
                } catch (e) { --> enters only on click of Save button of WI (unable to debug)
                    if (e instanceof TypeError) {
                        console.log("Error in estimationtoolurl script:", e);
                        result = workItem.getLabel('com.rtc.configuration.workitemtype.customattribute.link');
                    } else {
                        result = "Error in estimationtoolurl script:" + (e.message || e.toString()); // all I get from this kind of error message is Cannot find function xhrGet in object [object Object]
                    }
                }

            }
            return result;
        }
    });
})();


com.rtc.configuration.workitemtype.customattribute.tool -> a enumeration
com.rtc.configuration.workitemtype.customattribute.link -> a small html, where I want to place my generated url.

0 votes

Comments
There are a couple of things here:
 - dojo will only be defined if the code runs in the web client. The Calculated value script may run in a web client, Eclipse client and also on the server, so you need to know where the error is occurring
 - are you looking in the browser console for errors? The server logs will show server side errors so they are not relevant
 - did you try my approach and what error did you get?

Also I would fetch the data outside of the Calculated value script and cache it - it's not going to change much and your script is a huge performance problem right now. Calculate will run every time the data changes, and every save

1 vote

Davyd Norris, yes I did try.
As you mentioned, the script runs perfectly without any errors in the web browser — the URL gets generated without issues there.
However, the problem is in the ALM server logs (ccm.log). I used to get the error:
Error invoking value provider 'URLGenerator' associated with the attribute 'Link' in the project area with id ... "com.URLGenerator" is not a constructor.

So, I tried adding the xhrGet / your suggested jazzClient.xhrGet inside a try-catch block. After that, the issue in the logs disappeared.
But when I try to save the work item, the previously generated URL (already present in the Link attribute, generated seconds before the save) throws the following errors-
Error in estimationtoolurl script: "jazz" is not defined (from your suggestion), or
Cannot find function xhrGet in object [object Object] (from dojo.xhrGet).
Both are type errors. What I need is either a way to properly catch the error and always show the generated URL in all scenarios.

orFetch the timeline label associated with the assigned iteration of the WI. And I need it to run for every change.

The error messages are misleading, but what you are seeing is the expected behaviour. 

Neither dojo or jazz.client (which is a dojo package) are available on the server because they are web client libraries. What's happening is that the script is running perfectly in the web client and then it's running again on the server and breaking, so what you need to do is detect where the script is currently running and only run the calculation if it's running on the client, otherwise just return the current value of the attribute.

Simplest way to do that is add the following at the top of your script:

if (!jazz) {
  return workItem.getValue(attribute);
}

Your answer

Register or log in to post your answer.

Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.

Search context
Follow this question

By Email: 

Once you sign in you will be able to subscribe for any updates here.

By RSS:

Answers
Answers and Comments
Question details
× 460
× 35
× 22
× 1

Question asked: Aug 17, 3:36 a.m.

Question was seen: 375 times

Last updated: Aug 29, 12:26 a.m.

Confirmation Cancel Confirm