Pavlovia Experiment stuck on loading - SyntaxError: missing ) in parenthetical

URL of experiment: https://run.pavlovia.org/marchesini.id/comportamientolinguistico-pilot-1/html/?__pilotToken=baea999bd3c1653db9f7bb004df53ba1&__oauthToken=4dc65c23f14b542598aa670843b72662ab69dda70b5d2c2701e45e36bcd23bf3

Description of the problem:

I’m piloting my experiment on Pavlovia, but when I try to run it it stucks on “loading experiment”… If I go to the console, it says

"SyntaxError: missing ) in parenthetical "

I click on the syntax error line, and shows the following highlighted line:

if ( ( ( (timer.getTime() < 3) and mouse_3.getPressed and (mouse_3.isPressedIn(respuestaMasculino) or mouse_3.isPressedIn(respuestaFemenino)))) && muyRapido.status === PsychoJS.Status.NOT_STARTED) {

Thing is that the experiment runs Ok in Builder. The text component named “muyRapido” works just as it should work. In the builder, that stimuli starts On Condition:
(timer.getTime() < 3) and (mouse_3.getPressed) and ( mouse_3.isPressedIn(respuestaMasculino) or mouse_3.isPressedIn(respuestaFemenino) )

(I know the condition does not look well, but It’s the only way I found to make it work as I planned. )

I tried to edit manually on the gitlab project, for example to this :

 if ((( (timer.getTime() < 3) and (mouse_3.getPressed) and ( mouse_3.isPressedIn(respuestaMasculino) or mouse_3.isPressedIn(respuestaFemenino) ) ))) && muyRapido.status === PsychoJS.Status.NOT_STARTED) {

But it does not work either. It stucks on loading. Any ideas on what am I doing wrong?

Hi @imarchesini, I checked your parentheses and they look to line up correctly. I think this is an issue using and and or in JS. They are not the same as Pythons logical operators, you instead use && and || for (and, or) respectively.

if ( ( ( (timer.getTime() < 3) && mouse_3.getPressed && (mouse_3.isPressedIn(respuestaMasculino) || mouse_3.isPressedIn(respuestaFemenino)))) && muyRapido.status === PsychoJS.Status.NOT_STARTED) {

Also, isPressedIn is not actually a PsychoJS method. Have a look at the link to see how to code the equivalent in JS. You essentially have to check whether your object contains the mouse, and that simultaneously the mouse button has been pressed.

@dvbridges thank you very much!

Ok, so thanks to your advice I could make it run. My condition is now like this:

if ((( (timer.getTime() < 3) && (mouse_3.getPressed) && (respuestaMasculino.contains(mouse_3) || respuestaFemenino.contains(mouse_3)) )) && muyRapido.status === PsychoJS.Status.NOT_STARTED) {

I couldn’t check is it works yet, because now I have another problem. (let me know if it should go on another topic)

Now I get some ReferenceError: assignment to undeclared variable… " first it was on variable “frameDur”. I found that almost at the begining of the code there was this:

expInfo['frameRate'] = psychoJS.window.getActualFrameRate();
    if (typeof expInfo['frameRate'] !== 'undefined')
        frameDur = 1.0/Math.round(expInfo['frameRate']);
     else
       frameDur = 1.0/60.0; // couldn't get a reliable measure so guess

I just commented it as I don’t need the data of monitor framerate, and now I get the same ReferenceError on another variable “ConsentimientoClock”

I check again and there0s 3 references to that variable:

The first one is:

function experimentInit() {
  // Initialize components for Routine "Consentimiento"
  ConsentimientoClock = new util.Clock();
  Consentimiento_instrucciones = new visual.TextStim({
    win: psychoJS.window,
    name: 'Consentimiento_instrucciones',
    text: 'default text',
    font: 'Arial',
    units : undefined, 
    pos: [0, 0.2], height: 0.05,  wrapWidth: 1, ori: 0,
    color: new util.Color('white'),  opacity: 1,
    depth: 0.0 
  });

The second one:

function ConsentimientoRoutineBegin() {
  //------Prepare to start Routine 'Consentimiento'-------
  t = 0;
  ConsentimientoClock.reset(); // clock
  frameN = -1;
  // update component parameters for each repeat
  Consentimiento_instrucciones.setText(Consentimiento);
  buttonNext.setImage('C:\\Users\\kaini\\Desktop\\FACULTAD\\TESIS\\Psychopy exp\\estimulos\\siguiente2.jpg');
  // setup some python lists for storing info about the mouse_2
  mouse_2.clicked_name = [];
  gotValidClick = false; // until a click is received
  // keep track of which components have finished
  ConsentimientoComponents = [];
  ConsentimientoComponents.push(Consentimiento_instrucciones);
  ConsentimientoComponents.push(buttonNext);
  ConsentimientoComponents.push(mouse_2);
  
  for (const thisComponent of ConsentimientoComponents)
    if ('status' in thisComponent)
      thisComponent.status = PsychoJS.Status.NOT_STARTED;
  
  return Scheduler.Event.NEXT;
}

And the last one:

function ConsentimientoRoutineEachFrame() {
  //------Loop for each frame of Routine 'Consentimiento'-------
  let continueRoutine = true; // until we're told otherwise
  // get current time
  t = ConsentimientoClock.getTime();
  frameN = frameN + 1;// number of completed frames (so 0 is the first frame)
  // update/draw components on each frame
  
  // *Consentimiento_instrucciones* updates
  if (t >= 0.0 && Consentimiento_instrucciones.status === PsychoJS.Status.NOT_STARTED) {
    // keep track of start time/frame for later
    Consentimiento_instrucciones.tStart = t;  // (not accounting for frame time here)
    Consentimiento_instrucciones.frameNStart = frameN;  // exact frame index
    Consentimiento_instrucciones.setAutoDraw(true);
  }

As I understand, on the first one (experimentInit) it declares the variable ConsentimientoClock as “new util.Clock()” , so why does it say it is an undeclared variable? The other 2 places where it is called, are within the experiment Init (a “begin routine” and an “each frame”)

I also guess that, once I solve this, I will get another one and another one, as that routine is the first one of all 5 routines that I have.

I found only this thread Problem when trying to run online "ReferenceError:assignment to undeclared variable textwelc" (probably due to JavaScript wrong translation?) but turned out to be a Bool error that has already been fixed in an update.

Hi @imarchesini, this has happened because there was an error when your html/js was exported. You probably have either a “Failed to parse JS with esprima” error or a syntax error output somewhere e.g., your console. When I try to export the html with your task, I came up with an error related to your conditional above in your experimento routine, so you need to make that compatible with JS first and try again.

Thanks again!

Sorry to bother you, but just to make things clear, as I’m not very experienced in coding neither using psychopy…

I have to make it compatible with JS from Builder, then export to html, then upload to pavlovia? Or can I export the html that actually works in builder, and then on the gitlab modify the .js file for it to be compatible?

If I try to do the first thing, following the first link you gave me, I have to use a .getPressed() and .contains(mouse) condition, but it does not work as it does the “isPressedIn”. Instead of waiting for me to “click” the response, it just checks the .contains(mouse). I’m guessing that “getPressed” function might do different things in each case?

So, the first solution I provided for changing the conditional statement (e.g., replace and with &&) needs to be applied to the text component in your experimento routine. You can do all this from Builder. When that is fixed you should be able to get the html to compile correctly, and those errors will go away. The ReferenceErrors are occurring because there was a compiling error, which stops PsychoPy from defining all of your variables in the task.

However, you might need to rethink how you have programmed your task, and instead of having a text component start based on a condition, add a code component that determines whether or not to draw the text. This will make it easier to read. An example if some JS:

// Each Frame tab in a code component
if (someConditon && someCondition) {
  text.autoDraw = true;
}

Ok, so I following your suggestion, I think it’s better to determine whether to draw or not a text.

Based on this Two questions: (1) steps for generating the online version of my task (2) JS code

I set the code component on JS, and got it like this:

if (mouse_3.getPressed()[0] === 1) { // If left mouse button pressed 
  clickable = [respuestaFemenino, respuestaMasculino];  // clickable stim= my 2 img stims
  for (const obj of clickable) {  // for each clickable stim, check if it contains the mouse
    if (obj.contains(mouse)) {
      if (timer.getTime()<3) ) {
        muyRapido.autoDraw = True; //draw the text that alerts that the response is too fast
      } else if (timer.getTime()>6) ) {
        muyLento.autoDraw = True; //draw the text that alerts that the response is too slow;
      }
    mouse_3.setPos((0,0));
    thisExp.addData("RT", timer.getTime());
    continueRoutine = False;  //I want that if the stimuli is clicked, the routine ends (instead of forcing end routine on the component) 
    }
  }
}

However, it does not end the routine when I click the stim (running on psychopy). But, searching on other examples of the equivalent to “isPressedIn” and “continueRoutine”, the code seems to be ok, it’s basically the same that in the thread above.

Is it possible that , although it doesn’t work in Builder (because is in JS code)will instead iwork once uploaded to pavlovia?

Yes, your JS code will not run in Builder, you need to upload it to Pavlovia and run it from a browser. Soon, you will be able to run your PsychoJS task locally so you can debug your task, but for now you must run it from Pavlovia.

The code is looking good. A couple of things you will want to change with you JS code - True/False values are lowercase in JS e.g., muyLento.autoDraw = true;. Also, the call to save data is different in JS: psychoJS.experiment.addData('RT', timer.getTime());

Sorry to bother you, I actually try some things before coming here to ask for help, but still couldn’t solve it on my own… I’m getting the “Failed to parse as JS” error, and can’t either Sync to pavlovia.

I followed your advice, and changed the code component:

This is on “each frame” tab, in JS code type

if (mouse_3.getPressed()[0] === 1) { 
  clickable = [respuestaFemenino, respuestaMasculino];  
  for (const obj of clickable) {  
    if (obj.contains(mouse_3)) {
      if (timer.getTime()<3) ) {
        muyRapido.autoDraw = true; 
      } else if (timer.getTime()>6) ) {
        muyLento.autoDraw = true; 
      }
    mouse_3.setPos((0,0));
    psychoJS.experiment.addData('RT', timer.getTime());
    continueRoutine = false;   
    }
  }
}

Then i have a " timer = core.clock();" on “begin routine” and a "mouse_3.setPos((0,0)); " on end routine.

However, when I try to export the HTML , it shows the error you mentioned above: “Failed to parse as JS by esprima” (it gives the error 2 times)

Also, If I try to Sync with pavlovia, it get’s stuck on “Synchronizing…” and does not upload the repo. (with no error shown)

I searched and found what you’ve already told me about the lowercase in true/false but that’s already done. I have 2 other code components in other routines, that only have a “mouse.setPos((0,0))” line on begin or end routine tab. I tried cutting that line and pasting it in JS code type, for it to be "mouse.setPos((0,0)); " then compile, then export html but does the same. (also tried leaving those code components in Py code type, but same result)

EDIT:

So, I tried to do a fresh upload to pavlovia. And after I save the project, compile, export to html (with Failed parse as JS error…" , and start the new project on pavlovia, It shown this on the coder “output” tab:

AttributeError: ‘NoneType’ object has no attribute ‘project’
Traceback (most recent call last):
File “C:\Program Files (x86)\PsychoPy3\lib\site-packages\psychopy\app\pavlovia_ui\menu.py”, line 121, in onNew
syncProject(parent=self.parent, project=projEditor.project)
File “C:\Program Files (x86)\PsychoPy3\lib\site-packages\psychopy\app\pavlovia_ui\project.py”, line 488, in syncProject
infoStream=syncFrame.syncPanel.infoStream)
File “C:\Program Files (x86)\PsychoPy3\lib\site-packages\psychopy\app\pavlovia_ui\functions.py”, line 96, in showCommitDialog
changeDict, changeList = project.getChanges()
File “C:\Program Files (x86)\PsychoPy3\lib\site-packages\psychopy\projects\pavlovia.py”, line 915, in getChanges
raise ValueError(“Found an unexpected change_type ‘{}’ in gitpython Diff”.format(this.change_type))
ValueError: Found an unexpected change_type ‘U’ in gitpython Diff

Hi @imarchesini, failed to parse is a problem compiling the JS. This is probably because there were some extra parenthesis in your code. Try:

if (mouse_3.getPressed()[0] === 1) { 
  clickable = [respuestaFemenino, respuestaMasculino];  
  for (const obj of clickable) {  
    if (obj.contains(mouse_3)) {
      if (timer.getTime()<3) {
        muyRapido.autoDraw = true; 
      } else if (timer.getTime()>6) {
        muyLento.autoDraw = true; 
      }
    mouse_3.setPos((0,0));
    psychoJS.experiment.addData('RT', timer.getTime());
    continueRoutine = false;   
    }
  }
}

Thenk you very much !!

I could finally upload it to pavlovia and make it run. Now I have some other problems (the experiment runs ok but on the first rep of the loop in which the code component is, it just skips all the loop instead of going to the next sentence, but I’ll make a new topic for that.