Feedback after Block Rewritten in JavaScript for Online Studies

Does anybody know what would be the equivalent of the code below in JavaScript? I am trying to implement a “feedback after block”, as explained in https://www.psychopy.org/recipes/builderFeedback.html but then in JavaScript for an online study.

nCorr = trials.data['key_resp.corr'].sum() #.std(), .mean() also available
meanRt = trials.data['key_resp.rt'].mean()
msg = "You got %i trials correct (rt=%.2f)" %(nCorr,meanRt)

Hi @tjl, the method is slightly different, and requires your to sum the contents yourself because there are no built-in methods for summing as there are with Python.

// Get all correct
nCorr = 0
for (eachResp=0; eachResp<psychoJS.experiment._trialsData.length; eachResp++) 
{
  nCorr += psychoJS.experiment._trialsData[eachResp]['key_resp.corr'];
}

msg = "You got " + nCorr + " trials correct";
/**
To get the mean, sum the actual RTs as you do with the accuracy, then divide the RTs by the length of the `_trialsData` list use the length method e.g., `psychoJS.experiment._trialsData.length`.
*/

For a one-liner sum and mean method:

responses = psychoJS.experiment._trialsData  // get list of responses
nCorr = responses.reduce((a, b) => a + b['key_resp.corr'], 0)  // get sum
meanRT = responses.reduce((a, b) => a + b['key_resp.rt'], 0) / responses.length  // get mean
3 Likes

Dear @dvbridges ; thank you so much for the feedback. Does

refer to the reference .xlsx file and the trials in

to the name of the Loop?

Sorry, editing this response. The psychoJs.experiment is the experiment handler object. You can access the data from within using the _trialsData list of JS objects, which will include information about your current loop.

1 Like

Hi David, thank you again for this feedback. I tried the “one-liner sum and mean method” that you described and I do get the message in Pavlovia, however the nCorr shows up as “NaN” in the experiment. Is there something I did wrong in defining the nCorr variable? (The code below is what I have in the “Begin Route” part of the Code Component)

@tjl, would you mind sharing the URL to your task?

1 Like

Hi David, is this the URL you refer to (I set the settings to public so hopefully you can access it)?
https://pavlovia.org/timlameris/tjl_bpon_test_public_18-06

Hi @dvbridges I was just wondering if the link worked and if you could find anything incoherent in my definition of nCorr in the JavaScript?

Hi @tjl, the problem is that trialList also contains entries from your other routines, such as your practice routine. So, as you iterate through the list of JS objects, and key_resp_main.corr is not found (because that particular entry was for the practice routine, and only key_resp_practice.corr exists) you end up with a NaN value. To fix, you need to check that your trial entry is correct before adding to your nCorr variable. For this, you are better off using the long version of the code:

// Get all correct
nCorr = 0
for (eachResp=0; eachResp<psychoJS.experiment._trialsData.length; eachResp++) 
{
  if ('key_resp_main.corr' in psychoJS.experiment._trialsData[eachResp]) {
    nCorr += psychoJS.experiment._trialsData[eachResp]['key_resp_main.corr'];
  }
}
1 Like

Hi David,

My task runs fine in the builder and I’m now converting it to run online. I tried using the code above to print the number of correct trials to the screen after the practice block (before the main blocks begin):

Python code:

nCorr = trials_prac.data['resp_prac.corr'].sum() 
msg = "You got %i out of 8 trials correct" %(nCorr)

Adapted js code:

nCorr = 0
for (eachResp=0; eachResp<psychoJS.experiment._trialsData.length; eachResp++) 
{
  if ('resp_prac.corr' in psychoJS.experiment._trialsData[eachResp]) {
    nCorr += psychoJS.experiment._trialsData[eachResp]['resp_prac.corr'];
  }
}
msg = "You got" + nCorr + "out of 8 trials correct";

However I’m getting the following error in the web console when running it online, and was wondering if you knew what might be going wrong here?

Thank you! Do you know how I can edit this code so it works with the blocks inside the loop? As it is written now, it adds all correct data, even from previous blocks.

define it:

var msg;

before the loop

Hi @agleontyev thanks for this it’s cleared up the error with the msg. However I’m getting another error ‘Can’t find variable: eachResp’. I’ve tried defining this outside the loop too but no luck. Do you know what could be the problem here?

@rachel.rodrigues, try:

nCorr = 0
for (let eachResp=0; eachResp<psychoJS.experiment._trialsData.length; eachResp++) 
{
  if ('key_resp_main.corr' in psychoJS.experiment._trialsData[eachResp]) {
    nCorr += psychoJS.experiment._trialsData[eachResp]['key_resp_main.corr'];
  }
}

You need to use the let keyword to declare the variable in the for loop. Also, after you have made changes and synced with Pavlovia, try refreshing your browser cache, to make sure you are using the latest version of your task.

Hi agleontyev,

Wasn’t sure if this got a reply and have just been working on the same problem myself. My hack solution was to adjust the definition of the for loop so that instead of running through the entire _trialsData array, it starts N places from the end (for a block of length N). You would also need to use length N as a divider when working out means etc. In the code snippet: instead of “for (eachResp = 0;…”, start the for loop with eachResp = _trialsData.length - N.

However, with hindsight, probably would have been easier to add and then track my own variables within the trial loop rather than trying to guess where/how this stuff gets stored in the psychoJS object (or whatever it is).

Hi,
I am trying to implement this for my own study. I have 4 short blocks (eight trials each) and want to give accuracy feedback after each block on pavlovia. The long version posted above works for the first block, but afterwards I always get a NaN in the feedback msg. Followign the suggestion above, I guess I need to adjust
In the code snippet: instead of “for (eachResp = 0;…”, start the for loop with eachResp = _trialsData.length - N.
How do I do this? Is there a way to keep track of blocks (a counter) in JS?
You can see my code here
https://gitlab.pavlovia.org/henning/ab4

Any help/suggestion would be much appreciated

Hi Henning,

Here’s what I have for a similar problem:

pCorr = 0;
chunkLength = 8;
dataSoFar = psychoJS.experiment._trialsData;

for(var i = dataSoFar.length-chunkLength; i < dataSoFar.length; i++) {
    pCorr += dataSoFar[i]['key_resp.corr'];
}
pCorr = (100 * pCorr) / chunkLength; //dataSoFar.length;

meanRt = 0;
for(var i = dataSoFar.length-chunkLength; i < dataSoFar.length; i++) {
    meanRt += dataSoFar[i]['key_resp.rt'];
}
meanRt = meanRt / chunkLength; //dataSoFar.length;

Hello,
I’m using this JS code for feedback after a loop. The experiment is running in pilot mode and there are no error messages, and the message that appears is Hello World. So, that’s my question…what is wrong with my code that the message on the screen appears as Hello World?

// Get all correct
var msg;
var nCorr;
nCorr = 0;
for (let eachResp=0; eachResp<psychoJS.experiment._trialsData.length; eachResp++)
{
if (‘key_resp_2.corr’ in psychoJS.experiment._trialsData[eachResp]) {
nCorr += psychoJS.experiment._trialsData[eachResp][‘key_resp_2.corr’];
}
}
{
msg = “You got " + nCorr + " trials correct”;
}

@agleontyev