# Multiple conditional statements work correctly in PsychoPy but not PsychoJS

**URL:** <https://discourse.psychopy.org/t/multiple-conditional-statements-work-correctly-in-psychopy-but-not-psychojs/11575>\
**Category:** Online experiments\
**Tags:** pavlovia\
**Created:** [March 18, 2020, 6:48pm UTC](https://discourse.psychopy.org/t/multiple-conditional-statements-work-correctly-in-psychopy-but-not-psychojs/11575 "2020-03-18T18:48:44Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![andersoc](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/andersoc/32/7332_2.png) [@andersoc](https://discourse.psychopy.org/u/andersoc)\
**Post date:** [March 18, 2020, 6:48pm UTC](https://discourse.psychopy.org/t/multiple-conditional-statements-work-correctly-in-psychopy-but-not-psychojs/11575/1 "2020-03-18T18:48:44Z")

</div>

Description of the problem:

An experiment I’m building involves rating stimuli in a loop along two dimensions of emotion (valence and arousal) using two sliders appearing side by side. I want participants to press ‘enter’ after they input their responses along both sliders to complete a trial. The following condition statement works in Psychopy for a keyboard response component to become active:

Start condition: `$valenceRatingScale.rating and arousalRatingScale.rating`

However, the Pavlovia experiment page won’t load the experiment with this code. Is there an alternative way to do this? I’m not very familiar with Python or Javascript so I am pasting the routine’s code below.

This start condition for the keyboard component throws the following two error messages:

> ERROR Line 399: Unexpected identifier in newExperiment.js  
> ERROR Line 392: Unexpected identifier in newExperiment-legacy-browsers.js

Many thanks in advance!

```auto
# -------Run Routine "test"-------
while continueRoutine:
    # get current time
    t = testClock.getTime()
    tThisFlip = win.getFutureFlipTime(clock=testClock)
    tThisFlipGlobal = win.getFutureFlipTime(clock=None)
    frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    
    # *valenceRatingScale* updates
    if valenceRatingScale.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
        # keep track of start time/frame for later
        valenceRatingScale.frameNStart = frameN # exact frame index
        valenceRatingScale.tStart = t # local t and not account for scr refresh
        valenceRatingScale.tStartRefresh = tThisFlipGlobal # on global time
        win.timeOnFlip(valenceRatingScale, 'tStartRefresh') # time at next scr refresh
        valenceRatingScale.setAutoDraw(True)
    
    # *arousalRatingScale* updates
    if arousalRatingScale.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
        # keep track of start time/frame for later
        arousalRatingScale.frameNStart = frameN # exact frame index
        arousalRatingScale.tStart = t # local t and not account for scr refresh
        arousalRatingScale.tStartRefresh = tThisFlipGlobal # on global time
        win.timeOnFlip(arousalRatingScale, 'tStartRefresh') # time at next scr refresh
        arousalRatingScale.setAutoDraw(True)
    
    # *continuneText* updates
    if continuneText.status == NOT_STARTED and valenceRatingScale.rating and arousalRatingScale.rating:
        # keep track of start time/frame for later
        continuneText.frameNStart = frameN # exact frame index
        continuneText.tStart = t # local t and not account for scr refresh
        continuneText.tStartRefresh = tThisFlipGlobal # on global time
        win.timeOnFlip(continuneText, 'tStartRefresh') # time at next scr refresh
        continuneText.setAutoDraw(True)
    
    # *key_resp_10* updates
    waitOnFlip = False
    if key_resp_10.status == NOT_STARTED and valenceRatingScale.rating and arousalRatingScale.rating:
        # keep track of start time/frame for later
        key_resp_10.frameNStart = frameN # exact frame index
        key_resp_10.tStart = t # local t and not account for scr refresh
        key_resp_10.tStartRefresh = tThisFlipGlobal # on global time
        win.timeOnFlip(key_resp_10, 'tStartRefresh') # time at next scr refresh
        key_resp_10.status = STARTED
        # keyboard checking is just starting
        waitOnFlip = True
        win.callOnFlip(key_resp_10.clock.reset) # t=0 on next screen flip
        win.callOnFlip(key_resp_10.clearEvents, eventType='keyboard') # clear events on next screen flip
    if key_resp_10.status == STARTED and not waitOnFlip:
        theseKeys = key_resp_10.getKeys(keyList=['return'], waitRelease=False)
        _key_resp_10_allKeys.extend(theseKeys)
        if len(_key_resp_10_allKeys):
            key_resp_10.keys = _key_resp_10_allKeys[-1].name # just the last key pressed
            key_resp_10.rt = _key_resp_10_allKeys[-1].rt
            # a response ends the routine
            continueRoutine = False
    
    # check for quit (typically the Esc key)
    if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
        core.quit()
    
    # check if all components have finished
    if not continueRoutine: # a component has requested a forced-end of Routine
        break
    continueRoutine = False # will revert to True if at least one component still running
    for thisComponent in testComponents:
        if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
            continueRoutine = True
            break # at least one component has not yet finished
    
    # refresh the screen
    if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
        win.flip()

# -------Ending Routine "test"-------
for thisComponent in testComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
thisExp.addData('valenceRatingScale.response', valenceRatingScale.getRating())
thisExp.addData('valenceRatingScale.rt', valenceRatingScale.getRT())
thisExp.addData('valenceRatingScale.started', valenceRatingScale.tStartRefresh)
thisExp.addData('valenceRatingScale.stopped', valenceRatingScale.tStopRefresh)
thisExp.addData('arousalRatingScale.response', arousalRatingScale.getRating())
thisExp.addData('arousalRatingScale.rt', arousalRatingScale.getRT())
thisExp.addData('arousalRatingScale.started', arousalRatingScale.tStartRefresh)
thisExp.addData('arousalRatingScale.stopped', arousalRatingScale.tStopRefresh)
thisExp.addData('continuneText.started', continuneText.tStartRefresh)
thisExp.addData('continuneText.stopped', continuneText.tStopRefresh)
# check responses

```

---

<div class="post-metadata">

**Author:** ![andersoc](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/andersoc/32/7332_2.png) [@andersoc](https://discourse.psychopy.org/u/andersoc)\
**Post date:** [March 18, 2020, 7:56pm UTC](https://discourse.psychopy.org/t/multiple-conditional-statements-work-correctly-in-psychopy-but-not-psychojs/11575/2 "2020-03-18T19:56:52Z")

</div>

Update: The error only occurs when involving multiple conditions.  
The following works as a start condition:

```auto
$arousalRatingScale.rating

```

However, this doesn’t work:

```auto
$arousalRatingScale.rating and valenceRatingScale.rating

```

EDIT: I’ve found a work-around that does the trick for me.

---

<div class="post-metadata">

**Author:** ![Bobby\_Thomas](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/bobby_thomas/32/6618_2.png) [@Bobby\_Thomas](https://discourse.psychopy.org/u/Bobby_Thomas)\
**Post date:** [March 19, 2020, 2:36pm UTC](https://discourse.psychopy.org/t/multiple-conditional-statements-work-correctly-in-psychopy-but-not-psychojs/11575/3 "2020-03-19T14:36:05Z")

</div>

Hi, would you mind sharing the fix you found here so that others might benefit from it?

---

<div class="post-metadata">

**Author:** ![andersoc](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/andersoc/32/7332_2.png) [@andersoc](https://discourse.psychopy.org/u/andersoc)\
**Post date:** [March 19, 2020, 2:50pm UTC](https://discourse.psychopy.org/t/multiple-conditional-statements-work-correctly-in-psychopy-but-not-psychojs/11575/4 "2020-03-19T14:50:10Z")

</div>

Hi Bobby,

Thanks for the reminder! My work-around does not solve the problem regarding the multiple conditions.

Instead, I modified the start conditions of the components, making the second scale (arousalRatingScale) appear only after participants rate the first scale, making its start condition `valenceRatingScale.rating`.

I then used a polygon component to serve as a confirmation box and set its start condition to `arousalRatingScale.rating` .

Finally, I used a mouse component and set the confirmation box component as a clickable stimulus so that the routine ends after participants have rated both scales.

---

<div class="post-metadata">

**Author:** ![Bobby\_Thomas](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/bobby_thomas/32/6618_2.png) [@Bobby\_Thomas](https://discourse.psychopy.org/u/Bobby_Thomas)\
**Post date:** [March 19, 2020, 3:11pm UTC](https://discourse.psychopy.org/t/multiple-conditional-statements-work-correctly-in-psychopy-but-not-psychojs/11575/5 "2020-03-19T15:11:39Z")

</div>

Interesting fix. In the meantime I looked into the keyboard component more (I’ve only ever used time to enable it).  
I’m not positive why $arousalRatingScale.rating and valenceRatingScale.rating is working in PsychoPy but not PsychoJS, but I think it is because in JS _and_ is not a valid logical operator, it uses &&. Given this difference, I don’t think you can put a single statement in the start condition for the keyboard component that involves an and statement and have it work both locally and online.  
But I think an easy way around this issue would be to create a custom code component, and in the start routine tab have EnableKeyboard= False  
Then in the each frame tab you would define this locally (in Python) as  
EnableKeyboard= valenceRatingScale.rating and arousalRatingScale.rating  
Given the newest update to PsychoPy it should translate this to JS for you, but I think the manual translation would be  
EnableKeyboard=valenceRatingScale.rating && arousalRatingScale.rating

Then in the keyboard component you make your new start condition just $EnableKeyboard, and if you have built the code component correctly, this should work locally and online.

I understand if you don’t want to go back and try this solution since you have it working, but I figured I would put it here in case anyone else comes looking for help.

---

<div class="post-metadata">

**Author:** ![andersoc](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/andersoc/32/7332_2.png) [@andersoc](https://discourse.psychopy.org/u/andersoc)\
**Post date:** [March 19, 2020, 8:58pm UTC](https://discourse.psychopy.org/t/multiple-conditional-statements-work-correctly-in-psychopy-but-not-psychojs/11575/6 "2020-03-19T20:58:53Z")

</div>

Thank you very much for the suggestion! I’ll definitely try it out as I think it’s better than mine.

---

<div class="post-metadata">

**Author:** ![Angelika](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/angelika/32/43445_2.png) [@Angelika](https://discourse.psychopy.org/u/Angelika)\
**Post date:** [November 27, 2024, 4:02pm UTC](https://discourse.psychopy.org/t/multiple-conditional-statements-work-correctly-in-psychopy-but-not-psychojs/11575/7 "2024-11-27T16:02:29Z")

</div>

Hi there,  
Just as a follow-up on your thread, since I had the same question:  
I needed a conditional start for a button component, requiring two conditions to be fulfilled before the button would appear. Your suggestion to use `&&` as the logical operator worked really well in the builder.  
I hope this helps others.  
Cheers,  
Angelika
