Failed to parse as JS; code component for customised mouse response causing errors

URL of experiment: https://gitlab.pavlovia.org/jenny.retzler/memory_span

My experiment runs fine in builder and has some code components. I think it is my poor attempts at translating these to JS that is causing the error ‘failed to parse as JS by esprima’. The files upload to Pavlovia but the study gets stuck at the ‘initializing experiment’ screen. I suspect the problem is in the ‘Each frame’ block of the code associated with one routine and may relate to mouse.getPressedIn, but despite finding some relevant threads and looking at examples such as the Corsi blocks, I’ve been unable to solve the issue.

Begin routine (Python):

pracCount=pracCount+1
squares=[RSq1,RSq2,RSq3,RSq4,RSq5,RSq6,RSq7,RSq8,RSq9,RSq10,RSq11,RSq12,RSq13,RSq14,RSq15,RSq16]
clickSequence=[]
clickedSquare =[]
clickedSquareNum =[]

Begin routine (attempted JS equivalent):

pracCount=pracCount+1;
squares=[RSq1,RSq2,RSq3,RSq4,RSq5,RSq6,RSq7,RSq8,RSq9,RSq10,RSq11,RSq12,RSq13,RSq14,RSq15,RSq16];
clickSequence=[];
clickedSquare =[];
clickedSquareNum =[];

Each frame (Python):

for square in [RSq1,RSq2,RSq3,RSq4,RSq5,RSq6,RSq7,RSq8,RSq9,RSq10,RSq11,RSq12,RSq13,RSq14,RSq15,RSq16]:
    if mouse.isPressedIn(square):
        #find out the square name
        clickedSquare = square.name
        #extract the number only from the square name
        clickedSquareNum = int(''.join(filter(str.isdigit, clickedSquare)))
        #avoid double-clicks and add to clickSequence
        if clickSequence==[]:
            clickSequence.append(clickedSquareNum)
        elif clickedSquareNum!=clickSequence[-1]:
            clickSequence.append(clickedSquareNum)

# all clicked?
if len(clickSequence) >= len(respSequence):
    continueRoutine = False
    event.clearEvents()

Each frame (attempted JS equivalent):

    if (mouse.isPressedIn(square)){
        clickedSquare = square.name;
        clickedSquareNum = clickedSquare.replace(/[^0-9]/g,@'');
        if (clickSequence===[]){
            clickSequence.append(clickedSquareNum);
        }
        else if (clickedSquareNum!==clickSequence[-1]){
            clickSequence.append(clickedSquareNum);
        }
    }
}


if (clickSequence.length >= respSequence.length){
    continueRoutine = false;
}

End routine (Python):

thisExp.addData('clickSequence',clickSequence)


#determine if all items recalled, order doesn't matter

if list(set(clickSequence))==list(set(respSequence)):
    correctCount=correctCount+1

End routine (attempted JS equivalent):

psychoJS.experiment.addData('clickSequence',clickSequence)

if (clickSequence.length === respSequence.length && clickSequence.sort().every(function(value, index) { return value === respSequence.sort()[index]})=true){
    correctCount=correctCount+1;
}

There are one or two other very basic code components I can provide info for if needed, but I think it is unlikely that they are the issue.

Thanks in advance for any help - sorry for the long post!

Jenny

The last bit of code might be the reason. The code below is more readable, so try that and see if the error changes.

cs = clickSequence.sort();
rs = respSequence.sort();
sameLength = cs.length === rs.length;
diff = cs.filter(function(x) { return rs.indexOf(x) < 0 }).length;

if (sameLength && diff === 0) 
{
   correctCount = correctCount + 1;
}

There may also be an error with your regexp. you may need to remove the @ symbol.

clickedSquareNum = clickedSquare.replace(/[^0-9]/g,@'')

Hi @dvbridges

Thanks for the response. I made both of the changes and still had the error after your first suggestion, but removing the @ has stopped the ‘failed to parse’ message and it now starts to run.

However, I am now getting this error message:

  • TypeError: Cannot read property ‘0’ of undefined

From other threads it looks as though this has to do with the generation and updating of new variables within the script (so perhaps clickSequence, correctCount, etc), but it is not clear how to resolve the issue.

Many thanks for your help,
Jenny

Hi @jretz, I think this is related to the mouse settings and having “New clicks only” unticked. If you select “New ticks only”, the error should go away. This is a bug, and I am making the fix now.

1 Like

Perfect - that has done the trick. However, I am now seeing the following:

Unfortunately we encountered an error:

  • TypeError: mouse.isPressedIn is not a function

Try to run the experiment again. If the error persists, contact the experiment designer.

Again, looking on other forums it looks like this has come up before, but using that function has been suggested as a solution too (RatingScale in online experiments) - is this something that should be working? My clickable stimuli are slightly overlapping at the moment, so perhaps that could be causing issues. Incidentally, if I want square image stimuli for an online experiment would ‘height’ be the best unit to use?

Thank you!

@jretz, the isPressedIn function is not available on Pavlovia. However, it looks like you have already set up your experiment to take advantage of the mouse objects valid clicks, which stores the names of the objects clicked in the mouse object. You can change your code using the following for Python and JS. Note, with the JS, I have had to explicitly define the size of your squares in the Respond routine, because without the size the clicks are not detected. Replace your own code with the code below.

Python

# Each Frame
if len(mouse.clicked_name) >= len(respSequence):
    continueRoutine = False
    event.clearEvents()

# End routine
clickSequence = [int(click.replace("RSq", '')) for click in mouse.clicked_name]
thisExp.addData('clickSequence', clickSequence)

if list(set(clickSequence))==list(set(respSequence)):
    correctCount=correctCount+1

The JS equivalent:

////////// Begin Routine ////////// 

pracCount=pracCount+1;
squares=[RSq1,RSq2,RSq3,RSq4,RSq5,RSq6,RSq7,RSq8,RSq9,RSq10,RSq11,RSq12,RSq13,RSq14,RSq15,RSq16];
clickSequence=[];

// Change size of squares
// Need size to detect clicks
for (let i of squares)
  {i.setSize([.2, .4])}

////////// Each Frame ////////// 

// Convert respSequence to array
rs = JSON.parse(respSequence)

// Check number of squares clicked
if (mouse.clicked_name.length >= rs.length){
    continueRoutine = false;
}

////////// End Routine ////////// 

// Get click sequence
clickSequence = []
for (let each of mouse.clicked_name) {
    clickSequence.push(Number(each.replace('RSq', '')))
}

// Save click sequence
psychoJS.experiment.addData('clickSequence', clickSequence)

// Sort clicked and resp sequences for comparison
cs = clickSequence.sort((a, b) => a > b ? 1 : -1);
rs = rs.sort((a, b) => a > b ? 1 : -1)
sameLength = cs.length === rs.length;
diff = cs.filter(function(x) { return rs.indexOf(x) < 0 }).length;

if (sameLength && diff === 0) 
{
   correctCount = correctCount + 1;
}

Alternatively, here is a working version VS_Memory_Seq_Online - Copy.psyexp (151.2 KB)

1 Like

Hi @dvbridges . Thanks so much for the fix. It’s not quite doing what I need in terms of what it is allowing and what it is recording, but hopefully I’ll be able to make those adjustments myself with the code you’ve provided :slight_smile:

Jenny