Using ImageStim.contains() in JS to check which image was clicked

URL of experiment: https://pavlovia.org/run/jnasrini/m2s/html/

Description of the problem:
Hi Friends,

I’m trying to make a web demo of an experiment that checks which image the participant clicked and returns feedback depending on whether they clicked the correct one. I’ve managed to get most of the way through converting my python code snippet into JS, but I’ve gotten stuck on the error message below. I’m using the ImageStim.contains() method as I think it’s meant to be used, and it works on the desktop version, but I get the error below on Pavlovia.

Unfortunately we encountered an error:

TypeError: stimulus.contains is not a function
Try to run the experiment again. If the error persists, contact the experimenter.

This may very well be due to my limited knowledge of JS, but the experiment runs as expected on desktop. The JS code snippet I created for checking the stimulus is copied below, and the full js module is here: (https://gitlab.pavlovia.org/jnasrini/m2s/blob/master/html/M2S_Mockup.js)

  for (stimulus in [TopL, TopR, BottomL, BottomR]) {
      if (stimulus.contains(mouse_3)) {
          if (stimulus.image == Teach) {
              msg = "Good Monkey!";
              color = "green";
              }
          else {
              msg = "Bad Monkey!";
              color = "red";
              }
          }
      }

TopL, TopR, BottomL, BottomR are all ImageStim components that I’ve created in the prior routine.

Let me know if I can provide any other helpful info, and thanks so much for your time!

Best,
Jad

Hi @jnasrini, try changing the for loop from in to of. So,:

for (let stimulus of [TopL, TopR, BottomL, BottomR]) {...

There is a difference in JavaScript, where “of” allows you to iterate over the values of an iterable, whereas “in” allows you to iterate through the properties of an object. You may also want to change your conditional to account for button presses, because currently it will return true if the mouse is within the image, rather than clicked in the image.

1 Like

@dvbridges that did it! Works like a charm now. Thanks so much for your input.

re: accounting for button presses, I agree that would be a much more parsimonious solution, but I resorted to this approach because as far as I can tell from the documentation, PsychoPy JS doesn’t support the .isPressedIn() function I can access in Python.

It definitely works well enough for now since this code snippet is running immediately after a previous routine concludes with a mouse click on one of the stimuli, but I’ll keep an eye out for method updates to JS.

Thanks again!

Good spot @dvbridges

@jnasrini note also that PsychoPy mouse objects now support this sort of behaviour without you needing code at all. In the code below we allow the mouse to click on either the target or foil (but nothing else is considered a valid click) and then we store the name of the object “target” or “foil” and the name of the image (e.g. filename, assuming it is an image stim). This all works in both Python and JS outputs. :smile: