Mouse click on object error in Pavlovia but good on local PsychoPy

URL of experiment: test1 [PsychoPy]

Description of the problem:
I tried to set two texts for mouse clicks, and it didn’t work. So I used two squares in the back. It worked but once I chose to store the click (no matter what), it will not be able to run on Pavlovia.
Screenshot 2024-03-04 at 12.05.33 AM

Error code:
Unfortunately we encountered the following error:

  • TypeError: obj.contains is not a function
    Try to run the experiment again. If the error persists, contact the experiment designer.

I’m having the same issue

More information is needed, but here’s one solution.

1 Like

I read that thread but I’m not sure how to implement these changes in the builder.
Here is my code, the commented line is where the error occurs

type or paste code here
// check whether click was in correct object
          if (gotValidClick) {
              corr = 0;
              corrAns = corrans;
              for (let obj of [corrAns]) {
               // if (obj.contains(mouse_5)) {
                      corr = 1;
                  };
              };

Are you using a variable as the clickable stimulus for your mouse component?

What does it look like?

What version of PsychoPy are you using?

Yes, I’m using other object components as the clickable stimulus. I’m using verion 2024.1.1


Correct answers for mouse components don’t yet work online

Oh ok, is there a workaround?

I changed the experiment so the only clickable stimuli is the correct answer, but I’m still getting the same error:

type or paste code here
for (const obj of [corrans]) {
            if (obj.contains(mouse_5)) {
              gotValidClick = true;
              mouse_5.clicked_name.push(obj.name)
            }
          }

I tried adding “…” in front of the variable in the “Clickable stimuli” field, but I’m still seeing the same error.

Are you seeing the latest code? Check an incognito tab.

My workaround would be to allow all objects to be clicked without ending the routine and then check the clicked_name in Each Frame.

if mouse_5.clicked_name:
     if corrans in mouse_5.clicked_name:
          continueRoutine = False:

Thank you, it works now.

I also have an issue related to this…

In my experiment, participants have to choose an avatar that is later saved as a variable and used throughout the experiment. Since the PsychoPy builder solution does not work online, I have this component of code in begin routine:

// List of image file names
let avatar_files = [“image1.jpg”, “image2.jpg”, “image3.jpg”, “image4.jpg”];

// Positions for the 4 avatars
let positions = [[-0.3, 0.3], [0.3, 0.3], [-0.3, -0.3], [0.3, -0.3]];

// Shuffle positions so they appear randomly
util.shuffle(positions);

// Assign images to components in order
avatar1.setImage(avatar_files[0]);
avatar2.setImage(avatar_files[1]);
avatar3.setImage(avatar_files[2]);
avatar4.setImage(avatar_files[3]);

// Assign random positions to each
avatar1.setPos(positions[0]);
avatar2.setPos(positions[1]);
avatar3.setPos(positions[2]);
avatar4.setPos(positions[3]);

// Variables to store later
let chosen_avatar = null;
let opponent_avatars = null;

And this in end routine:
// Check for mouse clicks
let mouse_clicks = mouse.getPressed();

if (mouse_clicks[0]) { // Left button clicked
let avatars = [avatar1, avatar2, avatar3, avatar4];

for (let i = 0; i < avatars.length; i++) {
    if (avatars[i].contains(mouse)) {
        // Store chosen avatar
        chosen_avatar = avatar_files[i];

        // Get remaining avatars
        let remaining = avatar_files.filter(f => f !== chosen_avatar);

        // Randomly pick 2 opponents
        opponent_avatars = util.shuffle(remaining).slice(0, 2);

        // Save for later use
        expInfo['chosen_avatar'] = chosen_avatar;
        expInfo['opponent1'] = opponent_avatars[0];
        expInfo['opponent2'] = opponent_avatars[1];

        // Store in data file
        psychoJS.experiment.addData('chosen_avatar', chosen_avatar);
        psychoJS.experiment.addData('opponent1', opponent_avatars[0]);
        psychoJS.experiment.addData('opponent2', opponent_avatars[1]);
        
        continueRoutine = false;
        break; // stop checking once one avatar is chosen
    }
}

}

However, now it does not save anything and it does not end the routine..

Do you have the mouse component set to end the routine on a valid click on avatar1,avatar2,avatar3,avatar4 ?

You seem to be coding directly into JS rather than using auto translate.

No, the mouse component is not ending right now. Additionally, I have to code directly because I keep getting “variable is not defined” errors with the automatic translation.

How is the mouse component set to end?

See also:

Right now its on “never” but this is because valid click did not work and I did not know what to put.

Set it to end on valid click if you want it to end when one of the four avatars are clicked.

Then simplfy your code to use mouse*.clicked_*name

If you only end the routine with a mouse click, mouse.clicked_name should have the name of the avatar clicked on (probably in a list, e.g. [“avatar1”]

sorry for still asking,

but do you mean the routine would be:

if mouse.clicked_avatar1:

chosen_avatar = avatar1

elif mouse.clicked_…..

is this what you mean? i am so sorry for asking so much, I am just a bit lost