Migrating an experiment to v7.x¶
The release of version 7.0 changes a number of core components of jsPsych. We made these changes to improve jsPsych's compatibility with modern JavaScript tools like package managers and bundlers and to improve the developer experience for people contributing to jsPsych's codebase. We hope these changes will improve the long-term viability of the project and encourage more developers to contribute to jsPsych.
Our aim was to accomplish these goals with minimal changes to the user experience of jsPsych. However, we did have to change a few critical things. This guide is aimed at users who are familiar with v6.x of jsPsych and would like to understand what's changed in v7.x.
Loading jsPsych¶
There are now three different ways you can load jsPsych into your HTML file. We've updated the hello world tutorial to walk through each of the three options. If you are looking for the option that is most similar to the version 6.x experience, check out option 2. The biggest difference from what you are used to is that the directory structure of the downloaded library is slightly different and plugin files are named a little bit differently.
Initializing and running jsPsych¶
We've removed jsPsych.init()
and split the features into two different functions.
At the start of your experiment script, you'll now call initJsPsych()
to get a new instance of jsPsych and store it in a variable called jsPsych
.
This is where you will pass in the variety of parameters that used to go into jsPsych.init()
, with the exception of the timeline
parameter.
var jsPsych = initJsPsych({
use_webaudio: false,
on_finish: function(){
jsPsych.data.displayData();
}
});
Once you've created your timeline, then you'll launch the experiment by calling jsPsych.run()
, passing in the timeline as the only argument.
This is the point in your script where you've used the jsPsych.init
function in jsPsych v6.x.
Because the jsPsych.run
function only needs the experiment timeline, this argument should be an array (rather than an object like {timeline: timeline}
in jsPsych v6.x).
var timeline = [...]
jsPsych.run(timeline);
The type
parameter for trials¶
The type
parameter now expects the value to be a plugin class rather than a string.
For example, if you load the html-keyboard-response
plugin from the CDN...
<script src="http://unpkg.com/@jspsych/plugin-html-keyboard-response@1.1.0"></script>
... or from the plugin-html-keyboard-response.js
file in the release archive...
<script src="plugin-html-keyboard-response.js"></script>
... then a global variable defining the plugin's class called jsPsychHtmlKeyboardResponse
is available.
To create a trial using the plugin, pass this class as the type
parameter.
The plugin classes are named starting with jsPsych
, followed by the plugin name written in camel case (rather than with dashes between words).
See the "Using a plugin" section of the Plugins overview page for more examples.
Note that the value is not a string.
var trial = {
type: jsPsychHtmlKeyboardResponse,
stimulus: 'Hello, version 7.0!'
}
The choices
parameter for keyboard response trials¶
The choices
parameter for keyboard response trials no longer supports jsPsych.NO_KEYS
and jsPsych.ALL_KEYS
, and they have been replaced by the strings "NO_KEYS"
and "ALL_KEYS"
respectively.
For example, if you load the audio-keyboard-response
plugin, you can prevent any user input like...
var trial = {
type: jsPsychAudioKeyboardResponse,
choices: "NO_KEYS",
stimulus: 'example.ogg',
trial_ends_after_audio: true
}
Using extensions¶
Like plugins, extensions are now also referenced by their class.
Extensions are initiliazed in initJsPsych()
instead of jsPsych.init()
.
Extension classes are named similarly to plugins, except that they start with jsPsychExtension
.
var jsPsych = initJsPsych({
extensions: [
{type: jsPsychExtensionWebgazer}
]
})
The class is also used in trials that use the extension.
var trial = {
type: jsPsychHtmlKeyboardResponse,
stimulus: 'Hello, version 7.0!',
extensions: [
{type: jsPsychExtensionWebgazer}
]
}
Custom plugins¶
If you have custom plugins that you would like to upgrade to be compatible with v7.x we recommend using our plugin template.
The new template implements plugins as a class, but the core components are essentially unchanged.
- Anything in
plugin.info
from a v6.x plugin should be moved into theinfo
object. Note that thetype
argument for the parameters follows a slightly different syntax in the v7.x plugins. This object is then assigned as a static property of the class. - Anything in
plugin.trial
from a v6.x plugin should be moved into thetrial
method inside the class. - The new template has a
constructor()
function that accepts an instance of jsPsych. You do not need to adjust this portion of the plugin.
There are a few changes to be aware of that may affect your plugin code.
- We removed the
registerPreload
function and we now auto-detect media to preload via thetype
argument specified in theinfo
object. If a parameter is listed asIMAGE
,AUDIO
, orVIDEO
, it will be automatically preloaded. If you wish to disable preloading you can set thepreload
flag tofalse
for the parameter. - If you invoke any functions from jsPsych, like
jsPsych.finishTrial()
, note thatjsPsych
is no longer a global variable and you must use the reference to jsPsych that is passed to the constructor. To do this, simply prefix alljsPsych
references withthis.
, e.g.,jsPsych.finishTrial()
becomesthis.jsPsych.finishTrial()
. If your reference to a jsPsych function is inside of another function, then in order for thethis
keyword to appropriately reference the jsPsych instance, you must also use a JavaScript arrow function expression for the outer function. For example, this:Would be re-written as:function end_trial() { // ... jsPsych.finishTrial(data); }
const end_trial = () => { // ... this.jsPsych.finishTrial(data); }
Need help?¶
If you encounter issues migrating code to v7.x, feel free to post in our support thread for migration.