psychopy.org | Reference | Downloads | Github

Cannot read property 'length' of undefined (importConditions)

URL of experiment: https://gitlab.pavlovia.org/amazar/hea-4.git

Description of the problem: I keep getting the following error when trying to import a conditions file (“between.csv”) on Pavlovia:

TypeError: Cannot read property 'length' of undefined
    at Function.importConditions (https://run.pavlovia.org/amazar/hea-4/html/lib/data-2020.1.js:304:44)
    at Scheduler.trials_2LoopBegin [as _currentTask] (https://run.pavlovia.org/amazar/hea-4/html/Habit%20Attribution%20Experiment.js:614:29)
    at Scheduler._runNextTasks (https://run.pavlovia.org/amazar/hea-4/html/lib/util-2020.1.js:1091:18)
    at Scheduler._runNextTasks (https://run.pavlovia.org/amazar/hea-4/html/lib/util-2020.1.js:1094:31)
    at update (https://run.pavlovia.org/amazar/hea-4/html/lib/util-2020.1.js:1058:23)

Here is the relevant piece of code. It seems that the issue is with the specific line:

TrialHandler.importConditions(psychoJS.serverManager, 'between.csv', 'Math.floor(Math.random() * Math.floor(8))')
var trials_2;
var currentLoop;
function trials_2LoopBegin(thisScheduler) {
  // set up handler to look after randomisation of conditions etc
  trials_2 = new TrialHandler({
    psychoJS: psychoJS,
    nReps: 1, method: TrialHandler.Method.RANDOM,
    extraInfo: expInfo, originPath: undefined,
    trialList: TrialHandler.importConditions(psychoJS.serverManager, 'between.csv', 'Math.floor(Math.random() * Math.floor(8))'),
    seed: undefined, name: 'trials_2'
  });
  psychoJS.experiment.addLoop(trials_2); // add the loop to the experiment
  currentLoop = trials_2;  // we're now the current loop

Thanks!

Update: I tried using an xlsx file instead. Importing the file into psychopy builder seems to work fine - psychopy recognizes the correct number of conditions and parameters. When I try running the psychojs file locally in debug mode, though, I get an error message saying “unknown resource” (image below). The file (between.xlsx) exists in a folder titled “resources”, which is located within the folder that contains the main .js file, so I’m not sure why psychopy can’t read it.

I also changed the random integer function (‘Math.floor(Math.random() * Math.floor(8))’) to a simple integer (‘1’), which didn’t resolve the issue. Here’s the relevant line of code:

trialList: TrialHandler.importConditions(psychoJS.serverManager, 'between.xlsx', '1'),

Thoughts? Thanks!

Is there a specific reason you’re trying to manually code these instead of letting the builder do it?

Also, just comparing at some builder-generated code, you should just need to put ‘between.xlsx’ as the trialList argument rather than the importConditions call. So, try

trialList: 'between.xlsx'

and see if that simply works.

Thank you for the reply! importConditions was the default way that psychopy converted the data to JS.

In any case, I just avoided this issue by removing the “between.xlsx” file altogether. The original purpose was to have this file for between-subject condition, and have a column called “file” in there that has the names of 8 within-subject xlsx files (if this makes sense). Instead, I now just use a bunch of between-subject variables in the experiment info section to feed into the condition file name ($“dom”+expInfo[‘dom’]+“fin”+expInfo[‘fin’] + “habf” + expInfo[‘habf’] +".xlsx"), which is little clunky, but works.

I’m running into a different problem now, though. When I try to run the study on pavlovia, I get the error message

ReferenceError: $response is not defined
    at Scheduler.cor_loopLoopBegin [as _currentTask] (Habit Attribution Experiment.js:655) 

Looking at the relevant line of code, seems like this is a problem with my feedback loop for correct responses. This is how my experiment flow looks like:

The nreps argument for cor_loop is set to response.corr, meaning that if the response is correct (i.e. response.corr == 1), cor_loop should run, but not if the response is incorrect (i.e. response.corr == 0).

The “trial” routine, that comes right before cor_loop, doesn’t appear on the screen, so that likely has something to do with it, but I’m not sure how to correct that since I’m not getting an error message for that routine.

Thanks!

I see, so you’re using response.corr as nreps for the correct loop. I don’t think you can reference it like that (the period screws things up, among other issues), but there are other ways to do this. In your “trial” routine, add the following code component at “end routine” (this is python, but if you set the code type to auto->JS it should translate without issue):

if response.corr == 1:
    correctAns = True
else:
    correctAns = False

And then in your correct_3 routine, another code component in the “each frame” tab (again, python, but auto -> JS will work):

if correctAns == False:
    continueRoutine = False

Together, that should make it so that 1) you have a way of referencing response.corr outside of the trial routine and 2) if they got it wrong, then the correct_3 routine will not display (it needs to be in the each frame tab to skip properly).

Thanks! This fix did solve the error message. The “trial” and “correct_3” routines still don’t show up, though. Pavlovia doesn’t give an explicit error message when running the study - the instructions (first two routines) appear as normal, followed by a white screen instead of the “trial” and “correct_3” routines, and then the rest of the study (starting from “ask” routine) showing up properly for the most part (with a few seemingly-random errors).

Looking at the console, I found a bunch of warning about undefined attributes, mostly “size”:

Taking as an example the variable ‘target’, I don’t see a ‘size’ attribute, but I do see ‘height’, which is set to 0.1, so I’m not sure where the ‘size’ attribute for ‘target’ would be set:

// Initialize components for Routine "trial"
  trialClock = new util.Clock();
  target = new visual.TextStim({
    win: psychoJS.window,
    name: 'target',
    text: 'default text',
    font: 'Arial',
    units: undefined, 
    pos: [0, 0], height: 0.1,  wrapWidth: undefined, ori: 0,
    color: new util.Color([(- 1.0), (- 1.0), (- 1.0)]),  opacity: 1,
    depth: 0.0 
  });

Setting ‘units’ to ‘norm’ or ‘height’ didn’t solve the issue. In addition, I don’t see a ‘size’ property for text.stim in the documentation.

Now, because the study works fine offline, this made me think that something is funky with the html/js file exporting. I couldn’t pinpoint anything off with the html or js files on pavlovia (as far as I could tell). I tried removing and then re-creating the pavlovia repository, which didn’t help. I don’t know if it matters, but I noticed that when exporting the study to html, I see a message when the exporting process starts, but don’t see any message saying that it was exported successfully (below). The local html/js files seem fine, though.

Any idea how to approach this? In case it helps, here’s a link to the re-created repo. Thanks!

It looks like you’re defining what units you’re using in the experiment settings for most of the components except the sliders, which have their units defined in the component itself. That might be the source of the issue here. You could try either having the sliders use experiment settings for their units, or if that doesn’t work, try manually setting the unit type for each component (tedious, I know, but the easiest way to narrow down the issues).

My thinking is that “size” is a back-end property that PsychoJS uses to convert from whatever units you are using to the actual pixels it needs to display, which is why you can’t set it manually. If it’s not reading the unit types correctly, then that computation could fail in this way.

Okay, I figured it out! So, turns out that all of the stimuli that weren’t showing up were ones that had a variable position, taken from the .xlsx files. The .xlsx files had the position as a tuple, which works in psychopy, but psychojs reads as a string. So instead of having my position as one column (pos) in the format [0.3, 0.3], I separated it into two columns, one for posX and one for posY (with coordinates in each column simply as 0.3). I then set the position in Builder to $(posX, posY) .

Thanks!

2 Likes