JavaScript code doesn't execute properly | XM Community
Solved

JavaScript code doesn't execute properly

  • 3 August 2018
  • 8 replies
  • 375 views

Hello there,
on the last page of my survey, I do some JS calculations (getting answer values, doing calculations and setting embedded fields). The code in the last question (which only exists so I can execute JS code there) doesn't work properly. It seems to only work when I access/load the last page/question multiple (2 or 3) times by using the table of contents element.

I suspect my issue is similar to this (order of execution): https://www.qualtrics.com/community/discussion/199/using-javascript-with-embedded-data-and-or-selected-choices

However, my code is executed on a (last) separate block, page and question, so I don't know why it's not working.

Also I added some console.log elements so that I can track the code and according to the chrome dev console, it seems that the code is being executed twice, with two different VM IDs (all my debug.log(whatever) are showing twice).

Why is it being executed twice there?
Why do I have to load the page/question multiple times to get my question to work?
How can I get my code to execute only once and then work properly?

Thanks for any help!
icon

Best answer by CanerLC 8 August 2018, 15:11

View original

8 replies

Userlevel 7
Badge +27
1. It is executing twice because you are in preview mode. It executes once for the desktop frame and once for the mobile frame.
2. As for the code not executing properly, it is probably a timing issue. Two things you can do to address that: (a) Set page transition to 'None' under Look&Feel, (b) Add your code to the addOnReady function instead of the addOnload function.
1. Thanks for explaining that

2a) It's was already set to "none" the whole time
2b) I put the code into addOnLoad, but the problem still persists
Userlevel 7
Badge +27
On 2b, please re-read my original post. addOnLoad isn't even valid (case sensitive).

If what I suggested doesn't work, you'll have to post your code for anyone to help you further.
I meant "Qualtrics.SurveyEngine.addOnReady" of course.

This is my code:

Qualtrics.SurveyEngine.addOnload(function()
{

});

Qualtrics.SurveyEngine.addOnReady(function()
{
//FUNCTIONS -############################

function add(a, b) {
return a + b;
}

function roundTo(n, digits) {
var negative = false;
if (digits === undefined) {
digits = 0;
}
if( n < 0) {
negative = true;
n = n * -1;
}
var multiplicator = Math.pow(10, digits);
n = parseFloat((n * multiplicator).toFixed(11));
n = (Math.round(n) / multiplicator).toFixed(2);
if( negative ) {
n = (n * -1).toFixed(2);
}
return n;
}

// ACTUAL CODE ################################
console.log("START ##############################")
//PRODUKTION EINZELBEREICHE

//P1 -------------------------------------------------------------
console.log("P1 ----------------------------------")
var fragenP1 = [];
fragenP1.push(parseFloat("${q://QID257/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID258/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID259/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID260/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID261/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID262/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID263/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID264/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID265/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID266/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID267/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID268/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID269/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID270/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID271/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID272/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID273/SelectedChoicesRecode}"))
fragenP1.push(parseFloat("${q://QID274/SelectedChoicesRecode}"))

var sumP1 = fragenP1.reduce(add, 0)

console.log("Summe P1:" + sumP1)
console.log("Anzahl P1:" + fragenP1.length)

var avgP1 = sumP1/fragenP1.length

console.log("Durchschnitt P1: "+ avgP1)

avgP1 = roundTo(avgP1,2)

console.log("Gerundet P1: "+ avgP1)

Qualtrics.SurveyEngine.setEmbeddedData("avgP1", avgP1)


// ... analog code cut out here


//GESAMTDURCHSCHNITT BERECHNUNG

console.log("GESAMT DURCHSCHNITT ----------------------------------")

var bereiche = [];

if (avgP != "NaN") {
bereiche.push(parseFloat(avgP));
}
if (avgL != "NaN") {
bereiche.push(parseFloat(avgL));
}
if (avgQM != "NaN") {
bereiche.push(parseFloat(avgQM));
}
if (avgEV != "NaN") {
bereiche.push(parseFloat(avgEV));
}
if (avgEnt != "NaN") {
bereiche.push(parseFloat(avgEnt));
}

var sumGesamt = bereiche.reduce(add, 0)

console.log("Summe Bereiche: " + sumGesamt)
console.log("Anzahl Bereiche: " + bereiche.length)

var avgGesamt = sumGesamt/bereiche.length

console.log("avg Gesamt: "+ avgGesamt)

avgGesamt = roundTo(avgGesamt,2)

console.log("Gerundet Gesamt: "+ avgGesamt)

Qualtrics.SurveyEngine.setEmbeddedData("avgGesamt", avgGesamt )

});

Qualtrics.SurveyEngine.addOnUnload(function()
{

});


It's basically calculating averages in the survey horizontally.
Think participants can answer questions in areas A1, A2, A3 , B1, B2, B3, etc. and the code calculates the averages of A, B, C, D E and an overall average.

The tricky part is (also the reason why I chose to do it in JS) that A, B, C, D, E are optional, so participants pick 1 to 5 areas to answer and I need to account for that when calculating the averages. I have done that by using an array for areas A, B, C, D, E and divide by the array length, which accounts for the number of chosen areas.

I was using the scoring system and embedded data before, but couldn't find a way to dynamically divide by the number of areas chosen without using JS.


I am open to suggestions on how to achieve this in a better way, but executing the above code reliably is my primary concern now.
Is there anyone who can confirm this behavior?
Is this intended?
How can I secure the correct execution of my code without having to trigger the execution more than one time?

Any more help would be gladly appreciated.
Userlevel 7
Badge +27
@CanerLC,

Honestly, it would be a heck of a lot of work to recreate your survey and debug your JavaScript. That's probably why there hasn't been any response. If someone were to take it on, it would be helpful if you posted a .qsf of your survey to at least give them a starting point.
Thank you for the quick response.
I will try to fix/find the issue myself.

In the meantime I will try and execute the code twice manually, possibly copying the exact code to another subsequent question and see if this helps.

I will report back if I make any progress.
I found the problem.

Basically what was going wrong was that I tried to access/get some embedded data values which I also set in the very same code block.

I couldn't get some of the values during initial execution, because they were being set at the same time, hence the inconsistency

My solution is luckily very easy, because I can substitute the embedded data references with proper variable references, since I am initializing the variables during the first part of the calculations.

I should have better used them further down the line(s) again instead of embedded data fields.

Leave a Reply