Access variables in condition file and their use in code component (Java)

URL of experiment: Sign in · GitLab

Description of the problem:
I am trying to add a code component to my task in the builder, but I am not experienced with Java and I am finding issue in implementing what I am aiming for.

I want to make the feedback for every trial (fixation cross changing color to red for errors and to green for correct responses) conditional on a column of my condition file. I’m adding a code component in the routine in which I am collecting my responses (two button presses, key_resp and key_resp2)

The way I’m trying to do is to add in the BEGIN EXPERIMENT tab of my code component the following:

var Conditions psychoJS.experiment._trialsData

If I understood correctly, this should import the condition file in a Java-friendly way.

Then, in the END ROUTINE tab:

corr_l = Conditions.map((trial) => trial[trials.thisIndex,‘Corr_key_l’])
corr_r = Conditions.map((trial) => trial[trials.thisIndex,‘Corr_key_r’])

if ((resp_key.keys == corr_l) && (resp_key2.keys == corr_r)) {
color_feed = ‘green’
}
else color_feed = ‘red’
}

Then, obviously, the color of the fixation cross in the Feedback routine is set to change every repeat to $color_feed

The program is not throwing any error and runs smoothly online, but the fixation cross in the feedback is always changing to black.

Any suggestion on how to make this work?

Thank you!
Silvia

Hi @Silvia, with JavaScript it is normally right to declare your variables e…g, using var, but PsychoPy will do this for you, and create global variables that can be accessed throughout your task. If you use var in the code component, the variable will only be accessible in one part of the experiment, that is, it will be local to the beginning/middle of the experiment, routines etc. So, just remove the var and you are ok.

With var Condition psychoJS... you need to use the assignment operator = to set the value of Conditons e.g. Conditions = psychoJS.... However, this is not doing what you think it is doing. _trialsData is a private variable that contains your response (and other) data from the trials, and there are better options for you here than to use this variable.

If you set the correct answers for each trial in your conditions file, that you use in the loop in Builder, you can refer to those values during the experiment. E.g., add columns “corr_l” and “corr_r” to your conditions file, and fill them with the correct values. Then all you need in your code component is

if ((resp_key.keys == corr_l) && (resp_key2.keys == corr_r)) {
  color_feed = ‘green’
}
else { 
  color_feed = ‘red’
}

Dear @dvbridges, thanks a lot for your suggestion.

I tried to implement your code, but the feedback is still displayed in black.

Some things that might be relevant:

  • The correct responses are in my condition file, each cell of that variable contain the correct key that has to be pressed in that trial
  • The code component is in the routine in which i collect my responses and the part of code you suggested is now in the “end of routine” tab
  • The feedback routine is the following one. The color of the fixation cross is set to be updated at every repeat to $color_feed
  • In the piece of code you gave me above, the color is passed as a string to the variable color_feed. Is that OK?

Thanks,
Silvia

Hi @dvbridges,

sorry for asking again!

I made some progresses, but now I always get a red feedback. I have this in my code component:

if ((key_resp.key == Corr_key_r) && (key_resp_2.key == Corr_key_l)) {
  color_feed = 'green'
}
else { 
  color_feed = 'red'
}

Therefore, it is as if my first if statement is never True. I wonder if it has something to do with how the response keys are stored and named in Java. I have no idea how to access these info…

Thanks again for your help!

Silvia

HI @Silvia, if you fix the following I can take a look. You need an extra opening bracket at the beginning of the if statement:

  if (length(key_resp.keys) > 0) && (length(key_resp2.keys) > 0) {
      continueRoutine = False
      }

Thanks! I fixed it! :slight_smile:

Sorry, I did not see all the brackets. Just replace the block with:

if ( (length(key_resp.keys) > 0) && (length(key_resp2.keys) > 0) ) {
      continueRoutine = false
      }

It should be like that now

There is a typo in that code. The second keyboard should be key_resp_2. Nearly there.

Right!

Unfortunately, still no success both in the continueRoutine = False statement and in the conditional feedback (always red)

Again, thanks for all the help!

Sure that was just a bug that needed fixing, to get to the actual issue the task just needed to run correctly. Is there any chance you could create a minimal working example that gets straight to the issue? Currently there are 1000+ resources that need reloading and takes alot of time to load.

By the way, in JavaScript, you have to use lower case false (as in the example above).