TypeError: Cannot read properties of undefined (reading 'play')

URL of experiment: NonVerbalBehaviorStudy [PsychoPy]

Description of the problem:

I have completed my study on Pavlovia which is working fine on my end. I am now having lab members try out my experiment and some lab members are getting the following error:

TypeError: Cannot read properties of undefined (reading ‘play’)

This error appears right before a video is supposed to play. So they are able to go through my study until they reach “pressing play” where the study then crashes with that error. At that point, 1 of 6 videos i have assigned to different participant numbers should have played. This is working well for some users but crashes for others.

These are how I have my routines set up.

Video play routine:

Participant assigning routine:

This is the code for this step I believe:

‘’’ // Initialize components for Routine “video_play”
video_playClock = new util.Clock(); ‘’’

I think the code continues later like this further down:

‘’’ var video_studyClock;
var video_study;
var video_playComponents;
function video_playRoutineBegin(snapshot) {
return async function () {
TrialHandler.fromSnapshot(snapshot); // ensure that .thisN vals are up to date

//------Prepare to start Routine 'video_play'-------
t = 0;
video_playClock.reset(); // clock
frameN = -1;
continueRoutine = true; // until we're told otherwise
// update component parameters for each repeat
video_studyClock = new util.Clock();
video_study = new visual.MovieStim({
  win: psychoJS.window,
  name: 'video_study',
  units: 'height',
  movie: video_played,
  pos: [0, 0],
  size: [0.9, 0.507],
  ori: 0,
  opacity: 1,
  loop: true,
  noAudio: true,
  });
// keep track of which components have finished
video_playComponents = [];
video_playComponents.push(video_study);

for (const thisComponent of video_playComponents)
  if ('status' in thisComponent)
    thisComponent.status = PsychoJS.Status.NOT_STARTED;
return Scheduler.Event.NEXT;

}
}

function video_playRoutineEachFrame() {
return async function () {
//------Loop for each frame of Routine ‘video_play’-------
// get current time
t = video_playClock.getTime();
frameN = frameN + 1;// number of completed frames (so 0 is the first frame)
// update/draw components on each frame

// *video_study* updates
if (t >= 0.6 && video_study.status === PsychoJS.Status.NOT_STARTED) {
  // keep track of start time/frame for later
  video_study.tStart = t;  // (not accounting for frame time here)
  video_study.frameNStart = frameN;  // exact frame index
  
  video_study.setAutoDraw(true);
  video_study.play();
} '''

What is weird is that some users are getting the error and some are not using either windows or mac and similar browsers. The errors seem randomly spread. I’m using PsychoPy v2021.2.3 and built most of my experiment using the Builder but I synced the study using PsychoPy Coder to edit a small detail as a last step.

Again, this error is only happening for some users and it not happening for other participants. I’m really not sure how to address this issue.

I would appreciate any help with this as my study is being used for my thesis. Thank you very much

Giuliano

I suspect that the value of video isn’t set for some participants? Please could you copy and paste all of your code related to participant and video? Personally I would either assign the video more systematically using an incremental participant number or use the group variable in my VESPR Study Portal.

I basically have 160 participants watch 6 videos (slow, slow 2, modslow1, modslow 2, modfast and fast, split into 2 orders so that participants can see items in a counter balanced order (seeing items in order 1 and other items in order 2). I believe I properly put in my participants between 1-160 and this is what lab members were using. I have a lab member who used participant #3 and got the " [TypeError: Cannot read properties of undefined (reading ‘play’)" error right before the videos play. Participant #3 works on my end and has worked for other lab members too. But for some, it crashes at that exact place no matter what participant # they enter.

cd29855f-ca00-4fac-8bdb-ac957d15d08e

This is the code for the left side of Auto-JS where I enter things manually
‘’’
participant=int(expInfo[‘participant’])

if participant==4 or participant==27 or participant==48 or participant==58 or participant==73 or participant==81 or participant==101 or participant==120 or participant==129 or participant==148:

video=1

order=1

elif participant==3 or participant==20 or participant==35 or participant==60 or participant==72 or participant==85 or participant==108 or participant==114 or participant==141 or participant==151:

video=1

order=2

elif participant==15 or participant==25 or participant==45 or participant==49 or participant==79 or participant==96 or participant==111 or participant==127 or participant==134 or participant==149:

video=2

order=1

elif participant==14 or participant==31 or participant==36 or participant==62 or participant==68 or participant==95 or participant==103 or participant==125 or participant==132 or participant==146:

video=2

order=2

elif participant==5 or participant==18 or participant==47 or participant==51 or participant==78 or participant==84 or participant==98 or participant==122 or participant==139 or participant==156:

video=3

order=1

elif participant==16 or participant==26 or participant==46 or participant==54 or participant==70 or participant==86 or participant==112 or participant==116 or participant==143 or participant==157:

video=3

order=2

elif participant==2 or participant==32 or participant==42 or participant==56 or participant==71 or participant==87 or participant==110 or participant==121 or participant==133 or participant==145:

video=4

order=1

elif participant==13 or participant==24 or participant==44 or participant==64 or participant==77 or participant==83 or participant==109 or participant==118 or participant==142 or participant==150:

video=4

order=2

elif participant==9 or participant==23 or participant==37 or participant==53 or participant==80 or participant==89 or participant==100 or participant==128 or participant==140 or participant==159:

video=5

order=1

elif participant==12 or participant==28 or participant==40 or participant==59 or participant==75 or participant==92 or participant==107 or participant==117 or participant==130 or participant==153:

video=5

order=2

elif participant==11 or participant==19 or participant==39 or participant==55 or participant==66 or participant==82 or participant==104 or participant==126 or participant==137 or participant==152:

video=5

order=1

elif participant==7 or participant==21 or participant==38 or participant==50 or participant==65 or participant==90 or participant==106 or participant==113 or participant==144 or participant==155:

video=5

order=2

elif participant==6 or participant==22 or participant==43 or participant==52 or participant==76 or participant==94 or participant==97 or participant==124 or participant==135 or participant==154:

video=6

order=1

elif participant==8 or participant==29 or participant==34 or participant==63 or participant==69 or participant==91 or participant==105 or participant==119 or participant==138 or participant==160:

video=6

order=2

elif participant==1 or participant==17 or participant==41 or participant==61 or participant==67 or participant==93 or participant==102 or participant==123 or participant==131 or participant==158:

video=6

order=1

elif participant==10 or participant==30 or participant==33 or participant==57 or participant==74 or participant==88 or participant==99 or participant==115 or participant==136 or participant==147:

video=6

order=2

video_files = [‘videos/Glasses_slow1.mp4’,‘videos/Glasses_slow2.mp4’, ‘videos/Glasses_modslow1.mp4’,‘videos/Glasses_modslow2.mp4’, ‘videos/Glasses_modfast.mp4’, ‘videos/Glasses_fast.mp4’]

durations_s = [9.91, 9.81, 6.94, 6.87, 9.01, 4.67]

video_played = video_files[video-1]
video_duration=durations_s[video-1]

‘’’

This the corresponding code on the right JS side:
‘’’
participant = Number.parseInt(expInfo[“participant”]);
if (((((((((((participant === 4) || (participant === 27)) || (participant === 48)) || (participant === 58)) || (participant === 73)) || (participant === 81)) || (participant === 101)) || (participant === 120)) || (participant === 129)) || (participant === 148))) {
video = 1;
order = 1;
} else {
if (((((((((((participant === 3) || (participant === 20)) || (participant === 35)) || (participant === 60)) || (participant === 72)) || (participant === 85)) || (participant === 108)) || (participant === 114)) || (participant === 141)) || (participant === 151))) {
video = 1;
order = 2;
} else {
if (((((((((((participant === 15) || (participant === 25)) || (participant === 45)) || (participant === 49)) || (participant === 79)) || (participant === 96)) || (participant === 111)) || (participant === 127)) || (participant === 134)) || (participant === 149))) {
video = 2;
order = 1;
} else {
if (((((((((((participant === 14) || (participant === 31)) || (participant === 36)) || (participant === 62)) || (participant === 68)) || (participant === 95)) || (participant === 103)) || (participant === 125)) || (participant === 132)) || (participant === 146))) {
video = 2;
order = 2;
} else {
if (((((((((((participant === 5) || (participant === 18)) || (participant === 47)) || (participant === 51)) || (participant === 78)) || (participant === 84)) || (participant === 98)) || (participant === 122)) || (participant === 139)) || (participant === 156))) {
video = 3;
order = 1;
} else {
if (((((((((((participant === 16) || (participant === 26)) || (participant === 46)) || (participant === 54)) || (participant === 70)) || (participant === 86)) || (participant === 112)) || (participant === 116)) || (participant === 143)) || (participant === 157))) {
video = 3;
order = 2;
} else {
if (((((((((((participant === 2) || (participant === 32)) || (participant === 42)) || (participant === 56)) || (participant === 71)) || (participant === 87)) || (participant === 110)) || (participant === 121)) || (participant === 133)) || (participant === 145))) {
video = 4;
order = 1;
} else {
if (((((((((((participant === 13) || (participant === 24)) || (participant === 44)) || (participant === 64)) || (participant === 77)) || (participant === 83)) || (participant === 109)) || (participant === 118)) || (participant === 142)) || (participant === 150))) {
video = 4;
order = 2;
} else {
if (((((((((((participant === 9) || (participant === 23)) || (participant === 37)) || (participant === 53)) || (participant === 80)) || (participant === 89)) || (participant === 100)) || (participant === 128)) || (participant === 140)) || (participant === 159))) {
video = 5;
order = 1;
} else {
if (((((((((((participant === 12) || (participant === 28)) || (participant === 40)) || (participant === 59)) || (participant === 75)) || (participant === 92)) || (participant === 107)) || (participant === 117)) || (participant === 130)) || (participant === 153))) {
video = 5;
order = 2;
} else {
if (((((((((((participant === 11) || (participant === 19)) || (participant === 39)) || (participant === 55)) || (participant === 66)) || (participant === 82)) || (participant === 104)) || (participant === 126)) || (participant === 137)) || (participant === 152))) {
video = 5;
order = 1;
} else {
if (((((((((((participant === 7) || (participant === 21)) || (participant === 38)) || (participant === 50)) || (participant === 65)) || (participant === 90)) || (participant === 106)) || (participant === 113)) || (participant === 144)) || (participant === 155))) {
video = 5;
order = 2;
} else {
if (((((((((((participant === 6) || (participant === 22)) || (participant === 43)) || (participant === 52)) || (participant === 76)) || (participant === 94)) || (participant === 97)) || (participant === 124)) || (participant === 135)) || (participant === 154))) {
video = 6;
order = 1;
} else {
if (((((((((((participant === 8) || (participant === 29)) || (participant === 34)) || (participant === 63)) || (participant === 69)) || (participant === 91)) || (participant === 105)) || (participant === 119)) || (participant === 138)) || (participant === 160))) {
video = 6;
order = 2;
} else {
if (((((((((((participant === 1) || (participant === 17)) || (participant === 41)) || (participant === 61)) || (participant === 67)) || (participant === 93)) || (participant === 102)) || (participant === 123)) || (participant === 131)) || (participant === 158))) {
video = 6;
order = 1;
} else {
if (((((((((((participant === 10) || (participant === 30)) || (participant === 33)) || (participant === 57)) || (participant === 74)) || (participant === 88)) || (participant === 99)) || (participant === 115)) || (participant === 136)) || (participant === 147))) {
video = 6;
order = 2;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
video_files = [“videos/Glasses_slow1.mp4”, “videos/Glasses_slow2.mp4”, “videos/Glasses_modslow1.mp4”, “videos/Glasses_modslow2.mp4”, “videos/Glasses_modfast.mp4”, “videos/Glasses_fast.mp4”];
durations_s = [9.91, 9.81, 6.94, 6.87, 9.01, 4.67];
video_played = video_files[(video - 1)];
video_duration = durations_s[(video - 1)]; ‘’’

This is a pic of my psychopy first routine where this code is put.

This is how i skip orders in the different impression routines

‘’’
if order == 2:
continueRoutine = False
‘’’

I am not sure how to do those methods but I am open to suggestions resolving my problem. I think i covered all 160 participants in this code.

Let me know what you think is best or if you know how to resolve this issue.

I really appreciate the help.

Thanks again.

Giuliano

Hello Giuliano

you might want to simplify your video assignment based on participant number along the following lines:

if int(expInfo['participant']) % 2 == 0:
   order = 2
else:
   order = 1

gives you two orders based on the participant number (odd/even).

If you need more groups, simply extend the if-else construction (three groups):

if int(expInfo['participant']) % 3 == 0:
   order = 1
elif int(expInfo['participant']) % 3 == 1:
   order = 2
elif int(expInfo['participant']) % 3 == 2:
   order = 3

Best wishes Jens

I checked and all 160 participants are covered. Is it possible that the errors occur when a participant mis enters their number. Do you know if there are specific participant numbers causing the issue?

There could also be an issue related to the number of nested if statements, which @JensBoelte 's suggestion would help with.

It seems like using the incremental participant number using moryscarter.com for my pavlovia link solved the problem for people getting the error.

One participant told me that whenever he would put 3 in participant number, it would produce that error when he got to the video play but if he uses the moryscarter.com link, then it works. I have other people in my lab where putting 3 in participant number worked and they were able to run through study smoothly. It seems to be happening for some people, I still don’t understand why. The person getting the error says that if he enters 001 or 003, then the experiment runs smoothly but if he enters 3, he gets the error.

Anyways, it seems like using the moryscarter.com incremental assignment has solved my problem as this is what I will be using when running the study on Prolific.

Thank you very much for your support and help. You guys seem like a great community.

Giuliano

1 Like

Hi,

One thing to note about my incremental participant number tool is that it won’t know if a participant completes the study or not. For that functionality you would need the group variable in my VESPR Study Portal.