jatos.js Reference
jatos.js is a JavaScript library that helps you to communicate from your component's JavaScript with your JATOS server. Below we list and describe the variables and functions of the jatos.js library.
Always load the jatos.js script in the <head>
section with the following line:
<script src="jatos.js"></script>
or before version 3.3.1 with:
<script src="/assets/javascripts/jatos.js"></script>
All variables or calls to jatos.js start with jatos.
. For example, if you want to get the study's ID you use jatos.studyId
.
And, please, if you find a mistake or have a question don't hesitate to contact us.
jatos.js variables
You can call any of these variables below at any point in your HTML file after jatos.js finished initializing (jatos.onLoad()
will be called). Most variables are read-only. A few variables can be written into (e.g. jatos.httpTimeout
). Those are marked '(writeable)'.
IDs
All those IDs are generated and stored by JATOS. jatos.js automatically sets these variables with the corresponding values if you included the jatos.onLoad()
callback function at the beginning of your JavaScript.
jatos.studyId
- ID of the study which is currently running. All the study properties are associated with this ID.jatos.componentId
- ID of the component which is currently running. All the component properties are associated with this ID.jatos.batchId
- ID of the batch this study run belongs to. All batch properties are associated with this ID.jatos.workerId
- Each worker who is running a study has an ID.jatos.studyResultId
- This ID is individual for every study run. A study result contains data belonging to the run in general (e.g. Study Session).jatos.componentResultId
- This ID is individual for every component in a study run. A component result contains data of the run belonging to the specific component (e.g. result data).jatos.groupMemberId
- see Group Variablesjatos.groupResultId
- see Group Variables
There's a convenient function that adds all these IDs to a given object. See function jatos.addJatosIds(obj)
below.
Study variables
jatos.studyProperties
- All the properties (except the JSON input data) you entered for this studyjatos.studyProperties.title
- Study's titlejatos.studyProperties.uuid
- Study's UUIDjatos.studyProperties.description
- Study's descriptionjatos.studyProperties.descriptionHash
- Hash of study's descriptionjatos.studyProperties.locked
- Whether the study is locked or notjatos.studyProperties.dirName
- Study's dir name in the file system of your JATOS installationjatos.studyProperties.groupStudy
- Whether this is a group study or not
jatos.studyJsonInput
- The JSON input you entered in the study's properties.jatos.studyLength
- Number of component this study has
Original URL query parameters
jatos.urlQueryParameters
- Original query string parameters of the URL that starts the study. It is provided as a JavaScript object. This might be useful to pass on information from outside of JATOS into a study run, e.g. if you want to pass on information like gender and age. However if you know the information beforehand it's easier to put them in the Study's or Component's JSON input. Another example is MTurk which passes on it's worker's ID via a URL query parameter.Example: One has this link to start a Personal Single Run:
http://localhost:9000/publix/50/start?batchId=47&personalSingleWorkerId=506
Now one could add parameters to the URL's query string to pass on external information into the study run. E.g. the following URL would add the parameters 'foo' with the value 'bar' and 'a' with the value '123':
http://localhost:9000/publix/50/start?batchId=47&personalSingleWorkerId=506&foo=bar&a=123
Then those parameter will be accessible during the study run in
jatos.urlQueryParameters
as{a: "123", foo: "bar"}
.Example: MTurk uses for its worker ID the URL query parameter 'workerId' and this is accessible via
jatos.urlQueryParameters.workerId
.
Component variables
jatos.componentProperties
- All the properties (except the JSON input data) you entered for this componentjatos.componentProperties.title
- Component's titlejatos.componentProperties.uuid
- Component's UUIDjatos.componentProperties.htmlFilePath
- Path to Component's HTML file in your JATOS installationjatos.componentProperties.reloadable
- Whether it's reloadable
jatos.componentJsonInput
- The JSON input you entered in the component's properties.jatos.componentList
- An array of all components of this study with basic information about each component. For each component it has thetitle
,id
, whether it isactive
, and whether it isreloadable
.jatos.componentPos
- Position of this component within the study starting with 1 (like shown in the GUI)
Study's session data
The session data can be accessed and modified by every component of a study. It's a very convenient way to share data between different components. Whatever is written in this variable will be available in the subsequent components. However, remember that the session data will be deleted after the study is finished (see also Session Data - Three Types).
jatos.studySessionData
(writeable)
Other variables
All variables can be set except those labled read-only.
jatos.version
(read-only) - Current version of the jatos.js libraryjatos.channelSendingTimeoutTime
- Time in ms to wait for an answer after sending a message via a channel (batch or group). Set this variable if you want to change the default value (default is 10 s).jatos.channelSendingTimeoutTime = 20000; // Sets channel timeout to 20 seconds
jatos.channelHeartbeatInterval
- Waiting time in ms between channel (group or batch) heartbeats (default is 25 s)jatos.channelHeartbeatInterval = 10000; // Sets interval to 10 seconds
jatos.channelHeartbeatTimeoutTime
- Waiting time in ms for JATOS server's answer to a channel heartbeat (default is 10 s)jatos.channelHeartbeatTimeoutTime = 20000; // Sets interval to 20 seconds
jatos.channelClosedCheckInterval
- Waiting time in ms between checking if channels (group or batch) are closed unexpectedly (default is 2 s)jatos.channelClosedCheckInterval = 4000; // Sets interval to 4 seconds
jatos.channelOpeningBackoffTimeMin
andjatos.channelOpeningBackoffTimeMax
- Min and max waiting time (in ms) between channel reopening attempts (default is 1s for min and 2 min for max). jatos.js uses an exponential back-off retry pattern for the channels.jatos.channelOpeningBackoffTimeMin = 2000; // Sets interval to 2 seconds
jatos.channelOpeningBackoffTimeMax = 60000; // Sets interval to 1 minutejatos.httpTimeout
- Time in ms to wait for an answer of an HTTP request by jatos.js. Set this variable if you want to change the default value (default is 1 min).jatos.httpTimeout = 30000; // Sets HTTP timeout to 30 seconds
jatos.httpRetry
- Some jatos functions (e.g.jatos.sendResultData
) send an Ajax request to the JATOS server. If this request was not successful (e.g. network problems) jatos.js retries it. With this variable one can change the number of retries. The default is 5.jatos.httpRetry = 2; // Attempts 2 retries of failed Ajax requests
jatos.httpRetryWait
- Same asjatos.httpRetry
but this variable defines the waiting time between the retries. The default is 1000 ms.jatos.httpRetryWait = 5000; // Sets Ajax retry waiting time to 5 seconds
jatos.waitSendDataOverlayConfig
- (Since version 3.5.11) - Config of the overlay that is shown when the component ended but there are still data to be sent. See function jatos.showOverlay for config options. By default the text is "Sending data. Please wait." with an image of a spinning wheel.jatos.waitSendDataOverlayConfig = { text: "Enviando datos. Espere." };
General jatos.js functions
jatos.onLoad
Defines callback function that jatos.js will call when it's finished initialising.
- @param {function} callback - function to be called after jatos.js' initialization is done
Example
jatos.onLoad(function() {
// Start here with your code that uses jatos.js' variables and functions
});
jatos.addAbortButton
Since JATOS version >= 3.5.1 - Adds a button to the document that if pressed calls jatos.abortStudy (which cancels the study run and deletes all result data and files). By default this button is in the bottom-right corner but this and other properties can be configured.
- @param {object optional} config - Config object
- @param {string optional} text - Button text (Default: 'Cancel')
- @param {boolean optional} confirm - Should the worker be asked for confirmation? (Default: true)
- @param {string optional} confirmText - Confirmation text (Default: 'Do you really want to cancel this study?')
- @param {string optional} tooltip - Tooltip text (Default: 'Cancels this study and deletes all already submitted data')
- @param {string optional} msg - Message to be send back to JATOS to be logged (Default: 'Worker decided to abort')
- @param {string optional} style - Additional CSS styles
- @param {function optional} action - (since v3.5.11) Which function should be called in the end. Default is jatos.abortStudy.
Examples
Adds the default cancel button
jatos.addAbortButton()
Adds a cancel button and changes some properties
jatos.addAbortButton({
text: "Quit",
confirmText: "You really wanne quit?",
tooltip: "Don't you dare clicking here!",
msg: "This worker aborted the mission.",
style: "color:green"
});Adds a cancel button and changes the position to the bottom-left
jatos.addAbortButton({
style: "left:1em"
});Adds a cancel button and calls 'myFunction' if pressed
jatos.addAbortButton({
action: myFunction
});
jatos.showBeforeUnloadWarning
Since JATOS version >= 3.5.6 - Convenience function that adds or cancels a warning popup that will be shown by the browser to the worker who attempts to reload the page or close the browser (tab). By default this is turned on for components that are not 'reloadable'. Modern browsers do not allow to change the message of this popup. This works only if at least one user action happend in the window, e.g. mouse click (https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event).
- @param {boolean} show - If true the warning will be shown - if false a previously added warning will be canceled
Example
Adds a warning popup:
jatos.showBeforeUnloadWarning(true);
jatos.showOverlay
Since JATOS version >= 3.5.11 - Convenience function that shows a text and an image in the center of the screen. By default the text is 'Please wait.' and the image is an spinning wheel.
- @param {object optional} config - Config object
- @param {string optional} text - Text to be shown. Default is "Please wait".
- @param {string optional} imgUrl - URL of the image. Default is a spinning wheel.
- @param {string optional} showImg - If true the image is shown - otherwise not. Default is true.
- @param {string optional} style - Additional CSS styles
Examples
Shows the default overlay with 'Please wait.' and an spinning wheel.
jatos.showOverlay()
Shows text only
jatos.showOverlay({
text: "Please have a coffee break for 5 minutes",
showImg: false
});Shows text only
jatos.showOverlay({
text: "Please have a coffee break for 5 minutes",
imgUrl: "http://url-to-my-coffee-picture",
style: "color:brown"
});
jatos.removeOverlay
Since JATOS version >= 3.5.11 - Removes an overlay that was added by jatos.showOverlay.
Example
jatos.removeOverlay()
jatos.onError
DEPRECATED - use the specific function's error callback or Promise function instead
Defines a callback function that is to be called in case jatos.js produces an error.
- @param {function} callback - Function to be called in case of an error
Example
Show the error message in an alert box:
jatos.onError(alert);
jatos.log
Sends a message to be logged back to the JATOS server where it will be logged in JATOS' log file.
- @param {string} logMsg - The messages to be logged
Example
jatos.log("Log this message in JATOS' log file");
jatos.catchAndLogErrors
Since JATOS version >= 3.5.6 - Convenience function that sends all 'error' and 'unhandledrejection' events and 'console.error' and 'console.warn' calls to JATOS' server log. This is useful in debugging.
Example
jatos.catchAndLogErrors();
jatos.addJatosIds
Convenience function that adds some IDs (study ID, study title, batch ID, batch title, component ID, component position, component title, worker ID, study result ID, component result ID, group result ID, group member ID) to the given object.
- @param {object} obj - Object to which the IDs will be added
Example
var resultData = {};
jatos.addJatosIds(resultData);
jatos.setHeartbeatPeriod
Every running component sends regularly a HTTP request (the heartbeat) back to the JATOS server. This signals that it is still running. As soon as the browser tab running the component is closed the heartbeat ceases. The time of the last heartbeat is visible in the GUI, in the study results page in the 'Last Seen' row. This way you can easily see if a worker is still running your study or if (and when) he abandonend it. By default the heartbeat period is 2 minutes. By careful not to set the period too low (few seconds or even milliseconds) since it might overload your network or your JATOS server.
- @param {number} heartbeatPeriod - Time period between two heartbeats in milliseconds
Example
jatos.setHeartbeatPeriod(60000); // Sets to a heartbeat every minute
jatos.setStudySessionData
If you want to just write into the study session, this function is not what you need. If you want to write something into the study session, just write into the jatos.studySessionData
object.
Posts Study Session data to the JATOS server. This function sets the study session data and sends it to the JATOS server for safe storage. This is done automatically whenever a component finishes. But sometimes it is necessary to trigger this manually, e.g. in a very long-running component one might want to store the session intermediately. It offers callbacks, either as parameters or via a Promise, to signal success or failure in the transfer.
- @param {object} sessionData - object to be submitted
- @param {optional function} onSuccess - Function to be called after this function is finished
- @param {optional function} onFail - Function to be called after if this this functions fails
- @return {Promise}
Example
var studySessionData = { "a": 123, "b": 789, "c": 100};
jatos.setStudySessionData(studySessionData);
Functions to control study flow
jatos.startComponent
Finishes the currently running component and starts the component with the given ID. Though often it's better to use jatos.startComponentByPos
instead because it keeps working even after an export/import of the study into another JATOS. Since v3.3.1 one can additionally send result data back to the JATOS server.
Since v3.4.1 there are two version: with or without message
Without message:
- @param {number} componentId - ID of the component to start
- @param {optional object} resultData - (JATOS >= v3.3.1) String or object that will be sent as result data. An object will be serialized to JSON (stringify).
- @param {optional function} onError - Callback function if fail
With message (since JATOS >= v3.4.1):
- @param {number} componentId - ID of the component to start
- @param {optional object} resultData - String or object that will be sent as result data. An object will be serialized to JSON (stringify).
- @param {optional string} message - Message that should be logged (max 255 chars)
- @param {optional function} onError - Callback function if fail
Examples
Jump to component with ID 23
jatos.startComponent(23);
Since v3.3.1: send result data and jump to another component
var resultData = "my important result data";
jatos.startComponent(23, resultData);Since v3.4.1: send result data, jump to another component and send a message back that will be visible in JATOS result pages and log
var resultData = "my important result data";
jatos.startComponent(23, resultData, "everything okay");In versions < v3.3.1 it's often used together with
jatos.submitResultData
to first submit result data back to the JATOS server and afterwards jump to another componentvar resultData = "my important result data";
jatos.submitResultData(resultData, function() {
jatos.startComponent(23);
});
jatos.startComponentByPos
Finishes the currently running component and starts the component with the given position. The component position is the count of the component within the study like shown in the study overview page (1st component has position 1, 2nd component position 2, ...). Since v3.3.1 one can additionally send result data back to the JATOS server.
Since v3.4.1 there are two versions: with or without message
Without message
- @param {number} componentPos - Position of the component to start
- @param {optional object} resultData - (JATOS >= v3.3.1) String or object that will be sent as result data. An object will be serialized to JSON (stringify).
- @param {optional function} onError - Callback function if fail
With message (since JATOS >= v3.4.1)
- @param {number} componentPos - Position of the component to start
- @param {optional object or string} resultData - String or object that will be sent as result data. An object will be serialized to JSON (stringify).
- @param {optional string} message - Message that should be logged (max 255 chars)
- @param {optional function} onError - Callback function if fail
Examples
Jump to component in position 3
jatos.startComponentByPos(3);
Since v3.3.1: send result data and jump to component with position 3
var resultData = "my important result data";
jatos.startComponentByPos(3, resultData);Since v3.4.1: send result data, jump to component in position 3 and send a message back that will be visible in JATOS result pages and log
var resultData = "my important result data";
jatos.startComponentByPos(3, resultData, "everything okay");In versions < v3.3.1 it's often used together with
jatos.submitResultData
to first submit result data back to the JATOS server and afterwards jump to component in position 3var resultData = "my important result data";
jatos.submitResultData(resultData, function() {
jatos.startComponentByPos(3);
});
jatos.startNextComponent
Finishes the currently running component and starts the next component of this study. The next component is the one with position + 1. The component position is the count of the component within the study like shown in the study overview page (1st component has position 1, 2nd component position 2, ...). Since v3.3.1 one can additionally send result data back to the JATOS server.
Since v3.4.1 there are two versions: with or without message
Without message
- @param {optional object} resultData - (JATOS >= v3.3.1) String or object that will be sent as result data. An object will be serialized to JSON (stringify).
- @param {optional function} onError - Callback function if fail
With message (since JATOS >= v3.4.1)
- @param {optional object or string} resultData - String or object that will be sent as result data. An object will be serialized to JSON (stringify).
- @param {optional string} message - Message that should be logged (max 255 chars)
- @param {optional function} onError - Callback function if fail
Examples
Jump to the next component
jatos.startNextComponent();
Since v3.3.1: send result data and jump to the next component
var resultData = "my important result data";
jatos.startNextComponent(resultData);Since v3.4.1: send result data, jump to the next component and send a message back that will be visible in JATOS result pages and log
var resultData = "my important result data";
jatos.startNextComponent(resultData, "everything okay");In versions < v3.3.1 it's often used together with
jatos.submitResultData
to first submit result data back to the JATOS server and afterwards jump to the next componentvar resultData = "my important result data";
jatos.submitResultData(resultData, jatos.startNextComponent);
jatos.startLastComponent
Finishes the current component and starts the last component of this study. If the last component is inactive it starts the component with the highest position that is active. The component position is the count of the component within the study like shown in the study overview page (1st component has position 1, 2nd component position 2, ...). Since v3.3.1 one can additionally send result data back to the JATOS server.
Since v3.4.1 there are two versions: with or without message
Without message
- @param {optional object} resultData - (JATOS >= v3.3.1) String or object that will be sent as result data. An object will be serialized to JSON (stringify).
- @param {optional function} onError - Callback function if fail
With message (since JATOS >= v3.4.1)
- @param {optional object or string} resultData - String or object that will be sent as result data. An object will be serialized to JSON (stringify).
- @param {optional string} message - Message that should be logged (max 255 chars)
- @param {optional function} onError - Callback function if fail
Examples
Jump to the last component
jatos.startLastComponent();
Since v3.3.1: send result data and jump to the last component
var resultData = "my important result data";
jatos.startLastComponent(resultData);Since v3.4.1: send result data, jump to the last component and send a message back that will be visible in JATOS result pages and log
var resultData = "my important result data";
jatos.startLastComponent(resultData, "everything okay");
In versions < v3.3.1 it's often used together with
jatos.submitResultData
to first submit result data back to the JATOS server and afterwards jump to the last componentvar resultData = "my important result data";
jatos.submitResultData(resultData, jatos.startLastComponent);
jatos.abortStudy
Hint: There is a convenience function jatos.addAbortButton
that already adds a button to your document including showing an confirmation box and options to change it to your needs.
Aborts study. All previously submitted result data will be deleted. Afterwards the worker is redirected to the study end page. Data stored in the Batch Session or Group Session are uneffected by this.
- @param {optional string} message - Message that will be stored together with the study results and is accessible via JATOS' GUI result pages. The message can be max 255 characters long.
- @param {optional boolean} showEndPage - If 'true' an end page is shown - if 'false' it behaves like
jatos.endStudyAjax
, which means no showing of JATOS' end page
Examples
Just abort study
jatos.abortStudy();
Additionally send a message
jatos.abortStudy("participant aborted by pressing abort button");
jatos.abortStudyAjax
Hint: There is a convenience function jatos.addAbortButton
that already adds a button to your document including showing an confirmation box and options to change it to your needs.
Aborts study with an Ajax call. All previously submitted result data will be deleted. Data stored in the Batch Session or Group Session are uneffected by this. It offers callbacks, either as parameter or via a Promise, to signal success or failure in the ending.
- @param {optional string} message - Message that should be logged
- @param {optional function} onSuccess - Function to be called in case of successful submit
- @param {optional function} onError - Function to be called in case of error
- @return {Promise}
Examples
Just abort study
jatos.abortStudyAjax();
Abort study with a message that will be sent back to JATOS and shown in the result page and put in the log
jatos.abortStudyAjax("Worker clicked Abort button");
jatos.endStudy
Ends study. Redirects the worker to study's end page afterwards.
Since v3.4.1 there are two versions: with and without result data
With result data (since JATOS >= v3.4.1)
- @param {optional string or object} resultData - Result data to be sent back to JATOS server
- @param {optional boolean} successful - 'true' if study should finish successfully, 'false' otherwise. Default is true
- @param {optional string} message - Message that will be stored together with the study results and is accessible via JATOS' GUI result pages. The message can be max 255 characters long
- @param {optional boolean} showEndPage - If 'true' an end page is shown - if 'false' it behaves like
jatos.endStudyAjax
, which means no showing of JATOS' end page
Without result data
- @param {optional boolean} successful - 'true' if study should finish successfully, 'false' otherwise. Default is true
- @param {optional string} message - Message that will be stored together with the study results and is accessible via JATOS' GUI result pages. The message can be max 255 characters long
- @param {optional boolean} showEndPage - If 'true' an end page is shown - if 'false' it behaves like
jatos.endStudyAjax
, which means no showing of JATOS' end page
Examples
Just end study
jatos.endStudy();
End study and send a message back that will be visible in JATOS result pages and log
jatos.endStudy(true, "everything worked fine");
Indicate a failure - leads to study result state FAIL
jatos.endStudy(false, "internal JS error");
Send result data and end study (since JATOS >= v3.4.1)
var resultData = {id: 123, data: "my important result data"};
jatos.endStudy(resultData);Send result data, end study and send a message back that will be visible in JATOS result pages and log (since JATOS >= v3.4.1)
var resultData = {id: 123, data: "my important result data"};
jatos.endStudy(resultData, true, "everything worked fine");
jatos.endStudyAndRedirect
Since JATOS version >= 3.5.1 - Ends study and redirects the given URL. This is useful if you want to let the worker return to a recruitment platform (e.g. Prolific) or have your own end page. The same effect can be achieved with the Study Properties' End Redirect URL field. It offers callbacks, either as parameter or via a Promise, to signal success or failure in the ending.
Hint: There is a 'End Redirect URL' field in the Study Properties that also specifies the redirect URL. It's easier to use, but not as flexible.
- @param {string} url - URL of the page to be redirected to after the study run was successfully finished
- @param {optional boolean} successful - 'true' if study should finish successful - 'false' otherwise.
- @param {optional string} message - Message that will be stored together with the study results and is accessible via JATOS' GUI result pages. The message can be max 255 characters long.
- @param {optional function} onSuccess - Function to be called in case of successful submit
- @param {optional function} onError - Function to be called in case of error
- @return {Promise}
Examples
End study and redirect afterwards
jatos.endStudyAndRedirect("https://app.prolific.co/submissions/complete?cc=1234ABCD");
End study and redirect afterwards. Send result data.
var resultData = {id: 123, data: "my important result data"};
jatos.endStudyAndRedirect("https://app.prolific.co/submissions/complete?cc=1234ABCD", resultData);End study and redirect afterwards. A message will be sent back to JATOS and shown in the result page and put in the log.
jatos.endStudyAndRedirect("https://app.prolific.co/submissions/complete?cc=1234ABCD", true, "everything worked fine");
End study and indicate a failure and send a message. Does not redirect.
jatos.endStudyAndRedirect("https://app.prolific.co/submissions/complete?cc=1234ABCD", false, "internal JS error");
jatos.endStudyAjax
Ends study with an Ajax call - afterwards the study is not redirected to the JATOS' end page. If the study was run by an MTurk worker the confirmation code will be in the response. It offers callbacks, either as parameter or via a Promise, to signal success or failure in the ending.
- @param {optional boolean} successful - 'true' if study should finish successful - 'false' otherwise.
- @param {optional string} message - Message that will be stored together with the study results and is accessible via JATOS' GUI result pages. The message can be max 255 characters long.
- @param {optional function} onSuccess - Function to be called in case of successful submit
- @param {optional function} onError - Function to be called in case of error
- @return {Promise}
Examples
Just end study
jatos.endStudyAjax();
End study with a message that will be sent back to JATOS and shown in the result page and put in the log
jatos.endStudyAjax(true, "everything worked fine");
Indicate a failure and send a message
jatos.endStudyAjax(false, "some error description");
End study and show the confirmation code to the MTurk worker
jatos.endStudyAjax().then((confirmationCode) => {
// Show the confirmation code to the worker
});Use Promise to submit result data and afterwards, end the study and move to another URL (see also)
var resultData = {id: 123, data: "my important result data"};
jatos.submitResultData(resultData)
.then(jatos.endStudyAjax)
.then(() => { window.location.href = 'http://example.com/index.html' })
.catch(() => console.log("Something went wrong"));Send result data and end study (since JATOS >= v3.4.1)
var resultData = {id: 123, data: "my important result data"};
jatos.endStudyAjax(resultData);
Result data and result upload/download files
jatos.submitResultData
Posts result data for the currently running component back to the JATOS server. Already stored result data for this component will be overwritten. If you want to append result data use jatos.appendResultData
instead. Alternatively you can send result data with functions that jump to another component (e.g. jatos.startComponent
) or end the study (jatos.endStudy
). It offers callbacks, either as parameter or via a Promise, to signal success or failure in the transfer.
- @param {object} resultData - String or object that will be sent as result data. An object will be serialized to JSON.
- @param {optional function} onSuccess - Function to be called in case of successful submit
- @param {optional function} onError - Function to be called in case of error
- @return {Promise}
Examples
Send result data back to the JATOS server
var resultData = {"a": 123, "b": 789, "c": 100};
jatos.submitResultData(resultData);Since v3.3.1 it's possible to leave out the JSON serialization
var resultData = {"a": 123, "b": 789, "c": 100};
jatos.submitResultData(resultData);It's often used together with
jatos.startNextComponent
to first submit result data back to the JATOS server and afterwards jump to the next componentvar resultData = {"a": 123, "b": 789, "c": 100};
jatos.submitResultData(resultData, jatos.startNextComponent);
Or together with
jatos.startComponentByPos
to start a particular component (here at position 4)var resultData = {"a": 123, "b": 789, "c": 100};
jatos.submitResultData(resultData, () => { jatos.startComponentByPos(4) });Or by using the returned Promise
var resultData = {"a": 123, "b": 789, "c": 100};
jatos.submitResultData(resultData)
.then(() => console.log('success'))
.catch(() => console.log('error'));
jatos.appendResultData
Since JATOS version >= 3.1.7 - Appends result data to the already posted result data. Contrary to jatos.submitResultData
it does not overwrite the result data. Alternatively you can send result data with functions that jump to another component (e.g. jatos.startComponent
) or end the study (jatos.endStudy
). It offers callbacks, either as parameter or via a Promise, to signal success or failure in the transfer. This function can be used several times during an component run to incrementally save result data.
- @param {string} resultData - String or object that will be sent as result data. An object will be serialized to JSON (stringify).
- @param {optional function} onSuccess - Function to be called in case of successful submit
- @param {optional function} onError - Function to be called in case of error
- @return {Promise}
Examples
Append result data to the already sent
var resultData = { "a": 123, "b": 789, "c": 100};
jatos.appendResultData(resultData);Since v3.3.1 it's possible to leave out the JSON serialization
var resultData = {"a": 123, "b": 789, "c": 100};
jatos.appendResultData(resultData);Use mulitple
jatos.appendResultData
in a rowjatos.appendResultData({"a": 1})
.then(() => jatos.appendResultData({"b": 2}))
.then(() => jatos.appendResultData({"c": 3}))
.catch(() => console.log('Something went wrong'));You can use it together with
jatos.startNextComponent
to first append result data and afterwards jump to the next componentvar resultData = { "a": 123, "b": 789, "c": 100};
jatos.appendResultData(resultData, jatos.startNextComponent);Or by using the returned Promise
var resultData = {"a": 123, "b": 789, "c": 100};
jatos.appendResultData(resultData)
.then(() => jatos.startNextComponent())
.catch(() => console.log('Something went wrong'));Or together with
jatos.startComponentByPos
to start a particular component (here at position 4)var resultData = {"a": 123, "b": 789, "c": 100};
jatos.appendResultData(resultData)
.then(() => jatos.startComponentByPos(4))
.catch(() => console.log('Something went wrong'));
jatos.uploadResultFile
Since JATOS version >= 3.5.1 - Uploads a file to the JATOS server where they are stored in the server's file system (but not in the database). Similar to result data it can be downloaded in the JATOS UI, in the result pages. The files are stored per component - that means you can use the same filename without overwriting the file if the upload happens from different components. It offers callbacks, either as parameter or via a Promise, to signal success or failure in the transfer.
- @param {Blob, string or object} obj - Data to be uploaded as a file. Can be Blob, a string, or a object. A Blob will be uploaded right away. A string is turned into a Blob. An object is first turned into a JSON string and then into a Blob.
- @param {string} filename - Name of the uploaded file
- @param {optional function} onSuccess - Function to be called in case of success
- @param {optional function} onError - Function to be called in case of error
- @return {Promise}
Examples
Upload text
jatos.uploadResultFile("this is my data", "example.txt")
.then(() => console.log("File was successfully uploaded"))
.catch(() => console.log("File upload failed"));Upload object as JSON
var resultData = { "a": 123, "b": 789, "c": 100};
jatos.uploadResultFile(resultData, "example.json")
.then(() => console.log("File was successfully uploaded"))
.catch(() => console.log("File upload failed"));Upload text as Blob
var blob = new Blob(["Hello, world!"], {type: 'text/plain'});
jatos.uploadResultFile(blob, "example.txt")
.then(() => console.log("File was successfully uploaded"))
.catch(() => console.log("File upload failed"));Turn canvas into Blob and upload as image file. It assumes you have an canvas element with ID 'canvas'.
var canvas = document.getElementById('canvas');
canvas.toBlob((blob) => {
jatos.uploadResultFile(blob, "canvas.png")
.then(() => console.log("File was successfully uploaded"))
.catch(() => console.log("File upload failed"));
});For more real-world examples have a look at the 'Drawing' and the 'Video Recording' examples
jatos.downloadResultFile
Since JATOS version >= 3.5.1 - Downloads a file from the JATOS server. One can only download a file that was previously uploaded with jatos.uploadResultFile
in the same study run. If the file contains text it returns the content as a string. If the file contains JSON, it returns the JSON already parsed as an object. All other MIME types are returned as a Blob. It offers callbacks, either as parameter or via a Promise, to signal success or failure in the transfer.
- @param {string} filename - Name of the uploaded file
- @param {optional function} onSuccess - Function to be called in case of success
- @param {optional function} onError - Function to be called in case of error
- @return {Promise}
Additionally you can specify the component position from where the file was uploaded (in case different components uploaded files with the same filename)
- @param {number} componentPos - Position of the component where the file was uploaded
- @param {string} filename - Name of the uploaded file
- @param {optional function} onSuccess - Function to be called in case of success
- @param {optional function} onError - Function to be called in case of error
- @return {Promise}
Examples
Download text file
jatos.downloadResultFile("example.txt")
.then((text) => console.log(text))
.catch(() => console.log("File download failed"));Download JSON file
jatos.downloadResultFile("example.json")
.then((obj) => console.log(JSON.stringify(obj)))
.catch(() => console.log("File download failed"));Download image and display it in a canvas element
jatos.downloadResultFile("canvas.png")
.then((blob) => { document.getElementById("canvas").src = URL.createObjectURL(blob) })
.catch(() => console.log("File download failed"));Download file and specify that the file was uploaded in the first component
jatos.downloadResultFile(1, "example.txt")
.then((text) => console.log(text))
.catch(() => console.log("File download failed"));For more real-world examples have a look at the 'Drawing' and the 'Video Recording' examples
Batch
Batch variables
jatos.batchProperties
- All the properties you entered for this batch.jatos.batchProperties.allowedWorkerTypes
- List of worker types that are currently allowed to run in this batch.jatos.batchProperties.maxActiveMembers
- How many members this group can have at the same timejatos.batchProperties.maxTotalMembers
- How many members this group is allowed to have at the same timejatos.batchProperties.maxTotalWorkers
- Total amount of workers this group is allowed to have altogether in this batchjatos.batchProperties.title
- Title of this batch
jatos.batchJsonInput
- The JSON input you entered in the batch's properties.
Functions to access the Batch Session
The Batch Session is stored in JATOS' database on the server side (see also Session Data - Three Types). That means that all changes in the Batch Session have to be synchronized between the client and the server. This is done via the batch channel. Therefore all writing functions (add
, remove
, clear
, replace
, copy
, move
, set
, setAll
) can be paired with callback functions that will signal success or failure in the client-server sync. These callback functions can be either passed as parameters to jatos.batchSession.[function_name]
or via a Promise.
On the other side for all reading functions (get
, find
, getAll
, test
) there is no need to sync data between client and server, because jatos.js keeps a copy of the Batch Session locally. Therefore all reading functions do not offer callbacks, because there is no risk of failure of synchronization.
Additionally to the reading and writing functions the calback function jatos.onBatchSession(callback)
offers a way to get notified whenever the Batch Session changes in the JATOS' database regardless of the origin of the change. This way, you can have the client of each worker react to changes in the batch that were done by another worker in the batch.
Accessing the Batch Session is done via JSON Patches (RFC 6902) and JSON Pointer (RFC 6901). An introduction can be found under jsonpatch.com. For JSON Patches jatos.js uses the JSON-Patch library from Joachim Wester and for JSON Pointers the jsonpointer.js library from Alexey Kuzmin.
jatos.onBatchSession
Defines a callback function that is called every time the Batch Session changes on the JATOS server side (that includes updates in the session originating from other workers that run the study in parallel).
The callback function has two parameter (before v3.3.1 one parameter):
- @param {string} path - JSON pointer to the changed field in the Batch Session
- @param {string} op - (version >= 3.3.1) JSON patch operation ('add', 'remove', 'clear', ...) that was applied
Examples
Log whenever something changes in the Batch session
jatos.onBatchSession(function(path, op){
console.log("Batch Session was updated in path " + path + " with operation " + op);
});onBatchSession
is often used together withjatos.batchSession.find
to get the updated value:jatos.onBatchSession(function(path){
var changedObj = jatos.batchSession.find(path);
console.log("The changed object is " + JSON.stringify(changedObj));
});
jatos.batchSession.get
Convenience function: like jatos.batchSession.find
but works with a key instead of a JSON Pointer. Therefore it works only on the first level of the session's object tree. It takes a name of an field within the Batch Session and returns the matching value. For all other levels of the object tree use jatos.batchSession.find. Gets the object from the locally stored copy of the session and does not call the server.
- @param {string} name - name of the field
- @return {object} - the value that is stored under name
Examples
Get the value that belongs to a key in the Batch Session
If the Batch Session is
{"a": 1000, "b": "watermelon"}
// Since the parameter is the key's name and not a path it does not start with a "/"
var b = jatos.batchSession.get("b"); // b is "watermelon"
var c = jatos.batchSession.get("c"); // c is undefinedWith
jatos.batchSession.get
you can only access the first level of the object tree - if you want another level usejatos.batchSession.find
. If the Batch Session is{"a": {"a1": 123, "a2": "watermelon"}}
var a1 = jatos.batchSession.get("a1"); // a1 is undefined !!!
var a = jatos.batchSession.get("a"); // a is { "a1": 123, "a2": "watermelon" }
jatos.batchSession.set
A convenience function for jatos.batchSession.add
. Instead of a JSON Pointer path it accepts a name of the field to be stored (without a slash in front). Therefore it works only on the first level of the Batch Session's object tree. If the name already exists in the Batch Session the value will be overwritten.
- @param {string} name - name of the field
- @param {object} value - value to be stored
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Set a key and its value in the Batch Session
If the Batch Session is
{"a": 1234}
// Since the parameter is the key's name and not a path it does not start with a "/"
var b = jatos.batchSession.set("b", "koala");then after the Batch Session is successfully updated the new object is
{"a": 1234, "b": "koala"}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.batchSession.set("b", "koala")
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));Have a series of Batch Session changes
jatos.batchSession.set("a", 1)
.then(() => jatos.batchSession.set("b", 2))
.then(() => jatos.batchSession.set("c", 3))
.catch(() => console.log("Batch Session synchronization failed"));
jatos.batchSession.getAll
Returns the complete Batch Session data. Gets the object from the locally stored copy of the session and does not call the server.
- @return {object} Returns the whole Batch Session object
Example
var batchSession = jatos.batchSession.getAll();
jatos.batchSession.setAll
Replaces the whole session data. If the replacing object is rather large it might be better performance-wise to replace only individual paths. Each session writting involves sending the changes in the session via a JSON Patch to the JATOS server. If the session is large this data transfer can take some time. In this case use other session functions, like 'set', 'add', or 'replace'.
- @param {object} value - value to be stored in the session
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Set the whole Batch Session object
var o = {"a": 123, "b": "foo"};
jatos.batchSession.setAll(o); // Overwrites the current Batch Session with the object oSince there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
var o = {"a": 123, "b": "foo"};
jatos.batchSession.setAll(o)
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));
jatos.batchSession.clear
Clears the whole Batch Session data and sets it to an empty object {}
.
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Clear the whole Batch Session
jatos.batchSession.clear();
Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.batchSession.clear()
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));
jatos.batchSession.find
Gets a field in the Batch Session data. Takes a JSON Pointer and returns the matching value. Gets the object from the locally stored copy of the session and does not call the server. Contrary to jatos.batchSession.get
it allows to get values from all levels of the Batch Session's object tree.
- @param {string} path - JSON pointer path
- @return {object} - the value that is stored in path
Example
Find a field in the Batch Session
If the Batch Session is
{"a": {"a1": "foo", "a2": "bar"}, "b": 999}
jatos.batchSession.find("/a/a1"); // returns "foo"
jatos.batchSession.find("/b"); // returns 999
jatos.batchSession.defined
Since JATOS version >= 3.1.8 - Checks in the Batch Session whether a field under the given path exists. Returns true if the field is defined and false otherwise. It's equivalent to !jatos.batchSession.test(path, undefined)
.
- @param {string} path - JSON pointer path to be checked
- @return {boolean} - 'true' if the field is defined and 'false' otherwise
Example
jatos.batchSession.defined("/a"); // returns true if the pointer '/a' exists
jatos.batchSession.test
JSON Patch test operation: Tests that the specified value is set in the document (see jsonpatch.com).
- @param {string} path - JSON pointer path to be tested
- @param {object} value - value to be tested
- @return {boolean}
Examples
Test if a certain field in the Batch Session has a value
If the Batch Session is
{"a": 123, "b": {"b1": "flowers", "b2": "animals"}}
jatos.batchSession.test("/a", 123); // returns true
jatos.batchSession.test("/a", 10); // returns false
jatos.batchSession.test("/b/b1", "flowers"); // returns trueIf you want to know the existence of a path in the Batch Session you can test against
undefined
:if (!jatos.batchSession.test("/c", undefined)) {
// Path "/c" exists
} else {
// Path "/c" doesn't exist
}
jatos.batchSession.add
JSON Patch add operation: Adds a value to an object or inserts it into an array. In the case of an array, the value is inserted before the given index. The -
character can be used instead of an index to insert at the end of an array (see jsonpatch.com). If the path already exists in the Batch Session the value will be overwritten.
- @param {string} path - JSON pointer path
- @param {object} value - value to be stored
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Add to an empty Batch Session
jatos.batchSession.add("/a", 100);
After the Batch Session is successfully updated the new object is
{"a": 100}
.Add to Batch Session
If the Batch Session is
{"a": 100}
and one callsjatos.batchSession.add("/b", 123);
then after the Batch Session is successfully updated the new object is
{"a": 100, "b": 123}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or fail
jatos.batchSession.add("/b", 123)
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));Add an object:
jatos.batchSession.add("/obj", { foo: "bar" })
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));Afterwards the Batch Session contains
{"obj": {"foo": "bar"}}
.Add an array:
jatos.batchSession.add("/array", [1, 2, 3])
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));Afterwards the Batch Session contains
{"array": [1, 2, 3]}
.Add an element to an array:
If the Batch Session is
{"array": [1, 2, 3]}
and one callsjatos.batchSession.add("/array/2", "new")
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));then afterwards the Batch Session contains
{"array": [1, 2, "new", 3]}
.Append to the end of an array using
/-
:If the Batch Session is
{"array": [1, 2, 3]}
and one callsjatos.batchSession.add("/array/-", "new")
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));then afterwards the Batch Session contains
{"array": [1, 2, 3, "new"]}
.Have a series of Batch Session updates
jatos.batchSession.add("/a", 1)
.then(() => jatos.batchSession.add("/b", 2))
.then(() => jatos.batchSession.add("/c", 3))
.catch(() => console.log("Batch Session synchronization failed"));
jatos.batchSession.remove
JSON Patch remove operation: Removes a value from an object or array (see jsonpatch.com).
- @param {string} path - JSON pointer path to the field that should be removed
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Remove from the Batch Session
If the Batch Session is
{"a": 100, "b": 123}
and one callsjatos.batchSession.remove("/b");
then after the Batch Session is successfully updated the new object is
{"a": 100}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.batchSession.remove("/b")
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));
jatos.batchSession.replace
JSON Patch replace operation: Replaces a value. Equivalent to a 'remove' followed by an 'add' (see jsonpatch.com).
- @param {string} path - JSON pointer path
- @param {object} value - value to be replaced with
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Replace in the Batch Session
If the Batch Session is
{"a": 100, "b": 123}
and one callsjatos.batchSession.replace("/b", 789);
then after the Batch Session is successfully updated the new object is
{"a": 100, "b": 789}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.batchSession.replace("/b", 789)
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));
jatos.batchSession.copy
JSON Patch copy operation: Copies a value from one location to another within the JSON document. Both from and path are JSON Pointers (see jsonpatch.com).
- @param {string} from - JSON pointer path to the origin
- @param {string} path - JSON pointer path to the target
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Copy within the Batch Session from one location to another
If the Batch Session is
{"a": "jatos"}
and one callsjatos.batchSession.copy("/a", "/b");
then after the Batch Session is successfully updated the new object is
{"a": "jatos", "b": "jatos"}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.batchSession.copy("/a", "/b")
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));
jatos.batchSession.move
JSON Patch move operation: Moves a value from one location to the other. Both from and path are JSON Pointers. (see jsonpatch.com).
- @param {string} from - JSON pointer path to the origin
- @param {string} path - JSON pointer path to the target
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Move within the Batch Session from one location to another
If the Batch Session is
{"a": "jatos"}
and one callsjatos.batchSession.move("/a", "/b");
then after the Batch Session is successfully updated the new object is
{"b": "jatos"}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.batchSession.move("/a", "/b")
.then(() => console.log("Batch Session was successfully updated"))
.catch(() => console.log("Batch Session synchronization failed"));
jatos.batchSessionVersioning
Since JATOS version >= 3.5.6 - This flag can be used to turn off versioning of the batch session. This speeds up updates to the batch session (patches) in certain cases where all concurrent patches are conflict-free between each other. If versioning is turned on (set to true) all session data patches are accompanied by a version. On the JATOS server side only a patch with the current version (as stored in the database) is applied. If there are multiple concurrent patches only the first one is applied. If versioning is turned off all patches arriving at the JATOS server are applied right away without checking the version. This is faster but can lead to unintended session data changes. By default versioning is turned on.
Example
jatos.batchSessionVersioning = false; // Turns off versioning
Group studies
Group variables
The group variables are only filled with values if the current study run is a group study.
jatos.groupMemberId
- Group member ID is unique for this member (it is actually identical with the study result ID)jatos.groupResultId
- ID of this group result (It's called group result to be consistent with the study result and the component result - although often it's just called group)jatos.groupState
(Removed in JATOS >= v3.4.1) - Represents the state of the group in JATOS; only set if group channel is open (one of STARTED, FIXED, FINISHED)jatos.groupMembers
- List of member IDs of the current members of the groupjatos.groupChannels
- List of member IDs of the currently open group channels
Functions for group studies
jatos.joinGroup
Tries to join a group and if it succeeds opens the group channel (which is mostly a WebSocket). Only if the group channel is open one can exchange data with other group members. As the only parameter this function takes an object that consists of several optional callback functions that will be called by jatos.js when certain group events occur. It returns a Promise, to signal success or failure in joining.
- @param {object} callbacks - Defining callback functions for group events. All callbacks are optional. These callbacks functions are:
onOpen
: Is called when the group channel is successfully openedonClose
: Is be called when the group channel is closedonError
: Is called if an error during opening of the group channel's WebSocket occurs or if an error is received via the group channel (e.g. the Group Session data couldn't be updated). If this function is not defined jatos.js will try to call the globalonJatosError
function.onMessage(msg)
: Is called if a message from another group member is received. It gets the message as a parameter.onMemberJoin(memberId)
: Is called when another member (not the worker running this study) joined the group. It gets the group member ID as a parameter.onMemberOpen(memberId)
: Is called when another member (not the worker running this study) opened a group channel. It gets the group member ID as a parameter.onMemberLeave(memberId)
: Is called when another member (not the worker running his study) left the group. It gets the group member ID as a parameter.onMemberClose(memberId)
: Is called when another member (not the worker running this study) closed his group channel. It gets the group member ID as a parameter.onGroupSession(path, op)
: Is called every time the Group Session changes on the JATOS server side. It gets two parameters (before v3.3.1 only one): 1) JSON pointer path to the changed field in the Group Session as a parameter, and 2) JSON patch operation.onUpdate()
: Combines several other callbacks. It's called if one of the following is called:onMemberJoin
,onMemberOpen
,onMemberLeave
,onMemberClose
, oronGroupSession
.
- @return {Promise}
Examples
Minimal example that joins a group and receives updates via the Group Session
jatos.joinGroup({
"onGroupSession": onGroupSession
});
function onGroupSession(path, op) {
var changedObj = jatos.groupSession.find(path);
console.log("Group Session was updated in path " + path + " with operation " + op + " to " + JSON.stringify(changedObj));
}Example that defines the
onOpen
,onMemberOpen
, andonMessage
callbacksjatos.joinGroup({
"onOpen": onOpen,
"onMemberOpen": onMemberOpen,
"onMessage": onMessage
});
function onOpen() {
console.log("You joined a group and opened a group channel");
}
function onMemberOpen(memberId) {
console.log("In our group another member (ID " + memberId + ") opened a group channel");
}
function onMessage(msg) {
console.log("You received a message: " + msg);
}
jatos.sendGroupMsg
Sends a message to all group members with an open group channel. Use jatos.sendGroupMsgTo
to send a message to a particular member.
Between group members data can be exchanged in fundamentally two different ways: sendGroupMsg/sendGroupMsgTo or the Group Session. The main difference is that the Group Session is stored in JATOS database on the server side while with sendGroupMsg/sendGroupMsgTo the data are only relayed on the server side but is never stored. E.g. if the worker reloads the page all prior messages sent by sendGroupMsg/sendGroupMsgTo will be lost - on the other side, everything stored in the Group Session will be restored. But this storage of the Group Session in JATOS comes at the cost of being (slightly) slower. Which option to choose depends mostly on your study design. If you expect your workers to have an unreliable Internet connection or to reload the page then you should use the Group Session. If you just want to 'stream' current data to other members the use sendGroupMsg/sendGroupMsgTo.
- @param {object} msg - Any JavaScript object
Example
var msg = "Message for every group member"; // Send a text message
jatos.sendGroupMsg(msg)
var objMsg = {"city": "Berlin", "population": 3500000}; // Send an object
jatos.sendGroupMsg(objMsg)
jatos.sendGroupMsgTo
Like jatos.sendGroupMsg
but sends a message to a particular group member specified by the group member ID. You can find a list of all IDs of group members with an open channel jatos.groupChannels
. Alternativally you get member IDs via the onMemberOpen
callback function.
- @param {string} recipient - Recipient's group member ID
- @param {object} msg - Any JavaScript object
Examples
Send a message to a group member with ID 1063
var msg = "Message for group member 1063";
jatos.sendGroupMsgTo("1063", msg)Use the
onMemberOpen
callback to send a message right after a new member opened their group channeljatos.joinGroup({
"onMemberOpen": onMemberOpen,
"onMessage": onMessage
});
function onMemberOpen(memberId) {
var msg = "Welcome to the group!";
jatos.sendGroupMsgTo(memberId, msg);
}
function onMessage(msg) {
console.log("You received a message: " + msg);
}
jatos.leaveGroup
Leaves the group it has previously joined. It offers callbacks, either as parameter or via a Promise, to signal success or failure in the leaving.
- @param {optional function} onSuccess - Function to be called after the group is left
- @param {optional function} onError - Function to be called in case of error
- @return {Promise}
Example
jatos.leaveGroup();
jatos.reassignGroup
Asks the JATOS server to reassign this study run to a different group. JATOS can only reassign if there is another group availible. It offers callbacks, either as parameter or via a Promise, to signal success or failure in the reassigning.
- @param {optional function} onSuccess - Function to be called if the reassignment was successful
- @param {optional function} onFail - Function to be called if the reassignment was unsuccessful
- @return {Promise}
Example
jatos.reassignGroup()
.then(() => console.log("Successful group reassignment: new group ID is " + jatos.groupResultId))
.catch(() => console.log("Group reassignment failed"));
jatos.setGroupFixed
Ask the JATOS server to fix this group. A fixed group is not allowed to take on more members although members are still allowed to leave. It offers callbacks, either as parameter or via a Promise, to signal success or failure in the fixing.
- @param {optional function} onSuccess - Function to be called if the fixing was successful
- @param {optional function} onFail - Function to be called if the fixing was unsuccessful
- @return {Promise}
Example
jatos.setGroupFixed();
jatos.hasJoinedGroup
Returns true if this study run joined a group and false otherwise. It doesn't necessarily mean that we have an open group channel. We might just have joined a group in a prior component but in this component never opened the channel. If you want to check for an open group channel use jatos.hasOpenGroupChannel
.
Example
if(jatos.hasJoinedGroup()) {
// We are member in a group
} else {
// We are not member in a group
};
jatos.hasOpenGroupChannel
Returns true if we currently have an open group channel and false otherwise. Since you can't open a group channel without joining a group, it also means that we joined a group. On the other side although we have closed group channel we can still be a member in a group. Use jatos.hasJoinedGroup
to check group membership.
Example
if(jatos.hasOpenGroupChannel()) {
// We are member in a group and have an open group channel
} else {
// We do not have an open group channel (but could still be member in a group)
};
jatos.isMaxActiveMemberReached
Returns true if the group has reached the maximum amount of active members like specified in the batch properties. It's not necessary that each member has an open group channel.
Example
if(jatos.isMaxActiveMemberReached()) {
// Maximum number of active members is reached
};
jatos.isMaxActiveMemberOpen
Returns true if the group has reached the maximum amount of active members like specified in the batch properties and each member has an open group channel.
Example
if(jatos.isMaxActiveMemberOpen()) {
// Maximum number of active members is reached and each has an open channel
};
jatos.isGroupOpen
Returns true if all active members of the group have an open group channel and can send and receive data. It's not necessary that the group has reached its minimum or maximum active member size.
Example
if(jatos.isGroupOpen()) {
// Each of the current members of the group have an open group channel
};
Functions to access the Group Session
The Group Session is one of three way to communicate between members of a group. The others are direct messaging (with jatos.sendGroupMsgTo) and broadcast messaging (jatos.sendGroupMsg) (or: more general information about the different session types).
In difference to the Batch Session the Group Session doesn't work from the start of a component. To use the Group Session you have to join a group (with jatos.joinGroup). There you can also define a onGroupSession
callback that gets called each time the Group Session changes regardless of the origin of the change.
The Group Session is stored in JATOS' database on the server side. That means that all changes in the Group Session have to be synchronized between the client and the server. This is done via the group channel. Therefore all writing functions (add
, remove
, clear
, replace
, copy
, move
, set
, setAll
) can be paired with callback functions that will signal success or failure in the client-server sync. These callback functions can be either passed as parameters to jatos.groupSession.[function_name]
or via a Promise.
On the other side for all reading functions (get
, find
, getAll
, test
) there is no need to sync data between client and server, because jatos.js keeps a copy of the Group Session locally. Therefore all reading functions do not offer callbacks, because there is no risk of failure of synchronization.
Accessing the Group Session is done via JSON Patches (RFC 6902) and JSON Pointer (RFC 6901). An introduction can be found under jsonpatch.com. For JSON Patches jatos.js uses the JSON-Patch library from Joachim Wester and for JSON Pointers the jsonpointer.js library from Alexey Kuzmin.
jatos.groupSession.get
Convenience function: like jatos.groupSession.find
but works with a key instead of a JSON Pointer (without the slash in front of the key name). Therefore it works only on the first level of the session's object tree. It takes a name of an field within the Group Session and returns the matching value. For all other levels of the object tree use jatos.groupSession.find. Gets the object from the locally stored copy of the session and does not call the server.
- @param {string} name - name of the field
- @return {object} - the value that is stored under name
Examples
Get a field from the Group Session
Given the Group Session is
{"a": 1000, "b": "watermelon"}
// Since the parameter is the key's name and not a path it does not start with a "/"
var b = jatos.groupSession.get("b"); // b is "watermelon"
var c = jatos.groupSession.get("c"); // c is undefinedthe first line returns "watermelon" and the second undefined.
With
jatos.groupSession.get
you can only access the first level of the object tree - if you want another level usejatos.groupSession.find
.If the Group Session is
{"a": {"a1": 123, "a2": "watermelon"}}
var a1 = jatos.groupSession.get("a1"); // a1 is undefined !!!
var a = jatos.groupSession.get("a"); // a is { "a1": 123, "a2": "watermelon" }
jatos.groupSession.set
A convenience function for jatos.groupSession.add
. Instead of a JSON Pointer path it accepts a name of the field to be stored (without the slash in front). Therefore it works only on the first level of the Group Session's object tree. If the name already exists in the Group Session the value will be overwritten.
- @param {string} name - name of the field
- @param {object} value - value to be stored
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Set a field in the Group Session
If the Group Session is
{"a": 1234}
// Since the parameter is the key's name and not a path it does not start with a "/"
var b = jatos.groupSession.set("b", "koala");then after the Group Session is successfully updated the new object is
{"a": 1234, "b": "koala"}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.groupSession.set("b", "koala")
.then(() => console.log("Group Session was successfully updated"))
.catch(() => console.log("Group Session synchronization failed"));Have a series of Group Session changes
jatos.groupSession.set("a", 1)
.then(() => jatos.groupSession.set("b", 2))
.then(() => jatos.groupSession.set("c", 3))
.catch(() => console.log("Group Session synchronization failed"));
jatos.groupSession.getAll
Returns the complete Group Session data (might be bad performance-wise). Gets the object from the locally stored copy of the session and does not call the server.
- @return {object} Returns the whole Group Session object
Example
var groupSession = jatos.groupSession.getAll();
jatos.groupSession.setAll
Replaces the whole session data. If the replacing object is rather large it might be better performance-wise to replace only individual paths. Each session writting involves sending the changes in the session via a JSON Patch to the JATOS server. If the session is large this data transfer can take some time. In this case use other session functions, like 'set', 'add', or 'replace'.
- @param {object} value - value to be stored in the session
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Set the whole Group Session at once
var o = {"a": 123, "b": "foo"};
jatos.groupSession.setAll(o); // Overwrites the current Group Session with the object oSince there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
var o = {"a": 123, "b": "foo"};
jatos.groupSession.setAll(o)
.then(() => console.log("Group Session was successfully updated"))
.catch(() => console.log("Group Session synchronization failed"));
jatos.groupSession.clear
Clears the whole Group Session data and sets it to an empty object {}
.
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Clear the whole Group Session
jatos.groupSession.clear();
Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.groupSession.clear()
.then(() => console.log("Group Session was successfully updated"))
.catch(() => console.log("Group Session synchronization failed"));
jatos.groupSession.find
Gets a field in the Group Session data. Takes a JSON Pointer and returns the matching value. Gets the object from the locally stored copy of the session and does not call the server. Contrary to jatos.groupSession.get
it allows to get values from all levels of the Group Session's object tree.
- @param {string} path - JSON pointer path
- @return {object} - the value that is stored in path
Example
Given the Group Session is {"a": {"a1": "foo", "a2": "bar"}, "b": 999}
jatos.groupSession.find("/a/a1"); // returns "foo"
jatos.groupSession.find("/b"); // returns 999
the first line returns "foo" and the second 999.
jatos.groupSession.defined
Since JATOS version >= 3.1.8 - Checks in the Group Session whether a field under the given path exists. Returns true if the field is defined and false otherwise. It's equivalent to !jatos.groupSession.test(path, undefined)
.
- @param {string} path - JSON pointer path to be checked
- @return {boolean}
Example
jatos.groupSession.defined("/a"); // returns true if the pointer '/a' exists
jatos.groupSession.test
JSON Patch test operation: Tests that the specified value is set in the document (see jsonpatch.com).
- @param {string} path - JSON pointer path to be tested
- @param {object} value - value to be tested
- @return {boolean}
Example
Given the Group Session is {"a": 123, "b": {"b1": "flowers", "b2": "animals"}}
jatos.groupSession.test("/a", 123); // returns true
jatos.groupSession.test("/a", 10); // returns false
jatos.groupSession.test("/b/b1", "flowers"); // returns true
the first line returns true, second false and third true.
jatos.groupSession.add
JSON Patch add operation: Adds a value to an object or inserts it into an array. In the case of an array, the value is inserted before the given index. The -
character can be used instead of an index to insert at the end of an array (see jsonpatch.com). If the path already exists in the Group Session the value will be overwritten.
- @param {string} path - JSON pointer path
- @param {object} value - value to be stored
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Add an a field to the Group Session
If the Group Session is
{"a": 100}
and one callsjatos.groupSession.add("/b", 123);
then after the Group Session is successfully updated the new object is
{"a": 100, "b": 123}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.groupSession.add("/b", 123)
.then(() => console.log("Group Session was successfully updated"))
.catch(() => console.log("Group Session synchronization failed"));Example with an array: Put the object
{id: 123, name: "Max"}
after the second position of the array with the path/subjects
:jatos.groupSession.add("/subjects/2", {id: 123, name: "Max"})
.then(() => console.log("Group Session was successfully updated"))
.catch(() => console.log("Group Session synchronization failed"));Example of how to append to the end of an array: use
/-
after the arrays name:jatos.groupSession.add("/subjects/-", {id: 124, name: "Adam"})
.then(() => console.log("Group Session was successfully updated"))
.catch(() => console.log("Group Session synchronization failed"));Have a series of Group Session changes
jatos.groupSession.add("/a", 1)
.then(() => jatos.groupSession.add("/b", 2))
.then(() => jatos.groupSession.add("/c", 3))
.catch(() => console.log("Group Session synchronization failed"));
jatos.groupSession.remove
JSON Patch remove operation: Removes a value from an object or array (see jsonpatch.com).
- @param {string} path - JSON pointer path to the field that should be removed
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Remove a field from the Group Session
If the Group Session is
{"a": 100, "b": 123}
and one callsjatos.groupSession.remove("/b");
then after the Group Session is successfully updated the new object is
{"a": 100}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.groupSession.remove("/b")
.then(() => console.log("Group Session was successfully updated"))
.catch(() => console.log("Group Session synchronization failed"));
jatos.groupSession.replace
JSON Patch replace operation: Replaces a value. Equivalent to a “remove” followed by an “add” (see jsonpatch.com).
- @param {string} path - JSON pointer path
- @param {object} value - value to be replaced with
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Replace a field in the Group Session
If the Group Session is
{"a": 100, "b": 123}
and one callsjatos.groupSession.replace("/b", 789);
then after the Group Session is successfully updated the new object is
{"a": 100, "b": 789}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.groupSession.replace("/b", 789)
.then(() => console.log("Group Session was successfully updated"))
.catch(() => console.log("Group Session synchronization failed"));
jatos.groupSession.copy
JSON Patch copy operation: Copies a value from one location to another within the JSON document. Both from and path are JSON Pointers (see jsonpatch.com).
- @param {string} from - JSON pointer path to the origin
- @param {string} path - JSON pointer path to the target
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Copy a field in the Group Session from one location to another
If the Group Session is
{"a": "jatos"}
and one callsjatos.groupSession.copy("/a", "/b");
then after the Group Session is successfully updated the new object is
{"a": "jatos", "b": "jatos"}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.groupSession.copy("/a", "/b")
.then(() => console.log("Group Session was successfully updated"))
.catch(() => console.log("Group Session synchronization failed"));
jatos.groupSession.move
JSON Patch move operation: Moves a value from one location to the other. Both from and path are JSON Pointers. (see jsonpatch.com).
- @param {string} from - JSON pointer path to the origin
- @param {string} path - JSON pointer path to the target
- @param {optional callback} onSuccess - Function to be called if this patch was successfully applied on the server and the client side
- @param {optional callback} onError - Function to be called if this patch failed
- @return {Promise}
Examples
Move a field in the Group Session from one location to another
If the Group Session is
{"a": "jatos"}
and one callsjatos.groupSession.move("/a", "/b");
then after the Group Session is successfully updated the new object is
{"b": "jatos"}
.Since there is a slight chance that the session update was not successful it's a good idea to provide callback functions for both cases. To provide success or fail callback functions you can either specify the onSuccess/onError parameters or use the returned Promise.
Use returned Promise to handle success or failure
jatos.groupSession.move("/a", "/b")
.then(() => console.log("Group Session was successfully updated"))
.catch(() => console.log("Group Session synchronization failed"));
jatos.groupSessionVersioning
Since JATOS version >= 3.5.6 - This flag can be used to turn off versioning of the group session. This speeds up updates to the group session (patches) in certain cases where all concurrent patches are conflict-free between each other. If versioning is turned on (set to true) all session data patches are accompanied by a version. On the JATOS server side only a patch with the current version (as stored in the database) is applied. If there are multiple concurrent patches only the first one is applied. If versioning is turned off all patches arriving at the JATOS server are applied right away without checking the version. This is faster but can lead to unintended session data changes. By default versioning is turned on.
Example
jatos.groupSessionVersioning = false; // Turns off versioning