Description of the problem: When I click to pilot my experiment, I get through the dialog box, but then immediately get a frameDur error
when I check the javascript console, my error is related to code that was generated automatically by psychopy/pavlovia
// store frame rate of monitor if we can measure it successfully
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
Does anyone know how I can fix this?
I used the upload function directly from psychopy builder in version 2020.1.2
That’s weird. Most experiments don’t raise this error. Are you doing anything unusual? Do you have any Code Components (especially any that refer to frameDur)?
OK, so, in your JS file it turns out there’s no line var frameDur;
which is needed to define that variable name in JavaScript before it’s used. That line should have been generated while your experiment was compiled but seemingly wasn’t.
When you exported your study to html (e.g. by pressing sync) there wasn’t any message in PsychoPy was there, warning about invalid syntax maybe?
582.7943 ERROR Line 2685: Unexpected token && in 3b_complex_binctl.js
584.4439 ERROR Line 2689: Unexpected token && in 3b_complex_binctl-legacy-browsers.js
If I look at those lines in the code its referring to this block of code:
// start/stop star_sound
if (() && star_sound.status === PsychoJS.Status.NOT_STARTED) {
// keep track of start time/frame for later
star_sound.tStart = t; // (not accounting for frame time here)
star_sound.frameNStart = frameN; // exact frame index
If I search for the same string of code ( if (() && (...) that is causing the unexpected token issue there are 7 other places that I find it. They all seem to refer to sounds that have no defined (blank) onset or duration in the builder, and that are referred to in code components and called via mouse click in an object. The particular lines that it is having an issue with are not part of our code components, but seem to be the auto generated JS lines for the builder components. If I go into the .js and legacy-browsers.js files and manually take out the (() && and leave the rest of the line, it exports fine and reports as successful.
Thanks @fetch I’ll obviously need to look into the code being generated there. Why would you have a sound with no defined onset? Blank duration makes sense (means infinite) but I can’t think what blank onset should aim to do.
@jon we have an undefined onset because the sound plays on the condition of a mouse click in an object. I found another thread about changing “isClickedin” to a different call that is JS compatible, but that didn’t make a difference in this error. So all of the ones that have the issue with the code are ones that are set to onset/start as “on condition” and then the condition is defined in a code component referring to the mouse component.
@Xiaotong@jon I think these folks are getting similar errors to me. I went through and tried to add the var line but then it just throws the next error as an undefined INTROclock and then i added a var line to that, and it just jumps down to the next line and throws an error that wants you to add a var call to all of the variables throughout the entire code, so i just gave up.
I keep saying stop trying to fix the var statements. If the rest of your experiment is right then those will be added automatically. The issue with the var statements is caused by an issue with your study.
You need to find the component that’s breaking the code in the first place. When you remove things what causes the var lines to come back?
In @fetch 's case the these blank audio onsets are certainly an issue. If you want audio to start based on a certain condition then set that in the dialog box, rather than setting onset to be blank you need to set it to be start on condition and then set that conditional in the dialog box. Maybe you create a variable like startMySound and set that to True when you want the sound to play, but you can’t just leave the box blank. Doing that caused PsychoPy to write the code if (() && star_sound.status === PsychoJS.Status.NOT_STARTED)
which doesn’t make sense.
So it would be great if you could spend some time working out which parts of your code are breaking the compiling step and letting us know. Then we can start inserting things to alert users before that goes wrong like, “The onset of an object can’t be blank”
Hi jon, my problem starts from here Infinite initializing experiment. I don’t have a programming background so I just tried an easier way – removing import * as random from 'random'; import * as xlrd from 'xlrd';. Then I got the frameDur is not defined error. Thank you.
For Tom: yes that error message is informative. First off, it would be easier (for you to paste and for us to read) if you pasted in code as text. You cna just select the code and Ctrl-C. Come here and type 3 back ticks like this ``` then paste your code and then do three more backticks to end it.
Anyway, I can certainly see an issue with your code given your error message about the continue. Your Python code says
if 0 in obs_dict.values() or 1 in obs_dict.values():
continue
Now I don’t know what that code is meant to be doing (is it designed to skip the trial) but it isn’t really right, and that’s the part that then gets translated into something that fully raises an error in JavaScript. The issue is that the command continue doesn’t make sense in an “if” statement, only in a loop. Is the aim to skip over that trial?
if obs_dict == {}:
for image in trials.trialList:
image = image['object']
obs_dict[image] = 0
correct = False
loc = trials.thisTrial['loc']
image = trials.thisTrial['object']
if obs_dict[image] == 2:
if 0 in obs_dict.values() or 1 in obs_dict.values():
continue
else:
trials.finished = True
continue
Yes in a nutshell its meant to skip over a trial for which our learning criterion has been met (i.e., an object being placed in the correct location twice in a row). Then the last couple of lines were added because psychopy would crash when all the objects had been learned at the end of the routine.
Ah, OK. Yes, then I can see why that would work in the Python code (because that code is called within a loop of trials) but also why it won’t work in the current literal translation to JS (because that code is not then in a loop - it gets run inside a function). I’ll need to speak to someone with more JS skills to know what’s a sensible alternative for that.
It comes down to something like this. In the Routine where you currently have the continue you can do this
if obs_dict[image] == 2:
skipThisTrial = True # variable to use in feedback etc
continueRoutine = False # end this routine
if 0 not in obs_dict.values() and 1 not in obs_dict.values():
# end the whole trials loop
trials.finished = True
else:
skipThisTrial = False
The for your feedback routine you’d have something in the every frame to say:
if skipThisTrial:
continueRoutine = False
I think something like that would work in both Python and JS (it isn’t tested but you can hopefully see the logic).
Again the issue is that, for the Python code, this is being executed in a loop whereas for the JS code it is not, so we need a different way to handle it
Thanks Jon, the code you sent makes sense but still doesn’t work - exactly when the whole trials loop is due to end I get this:
if mouse.x[0] in range(pos[0]-150, pos[0]+150):
IndexError: list index out of range
Also - something you might want to know - i tried to upload the task without any code components added and I STILL had the error of variables not being defined which surprised me. A much,much stripped down version of the task exists (my second session task) and this works fine so I just assumed it was the code component causing the trouble but apparently it isn’t. I’ll try and find out exactly where the problem is and get back to you.