Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation needed for plugin template and bundlers #3047

Open
jodeleeuw opened this issue May 23, 2023 Discussed in #3046 · 0 comments
Open

Documentation needed for plugin template and bundlers #3047

jodeleeuw opened this issue May 23, 2023 Discussed in #3046 · 0 comments

Comments

@jodeleeuw
Copy link
Member

Discussed in #3046

Originally posted by SHogenboom May 23, 2023
I’m having issues getting a custom plugin to work/integrate within my jsPsych experiment. It’s most likely an issue with scoping / modules - which I don’t quite understand. I therefore have a hard time figuring out why I cannot get the template to work - irrespective of it’s contents.

I’m using a setup of npm and Parcel (bundler) to serve and test the code. I’m doing this to ultimately bundle and optimize all .js files so they can be integrated in online survey software Limesurvey. The files consist of:

experiment.html (entrypoint)

<!DOCTYPE html>
<html>
  <head>
    <title>The Word Association Task</title>
    <script type="module" src="js/experiment.js"></script>
  </head>
  <body></body>
</html>

experiment.js (main flow)

// npm install jspsych
import { initJsPsych } from "jspsych"; // general functionality
import "jspsych/css/jspsych.css"; // jspsych styling (e.g., center on screen)
// custom plugin
import { jsPsychWordAssociationGame } from "./jsPsychWordAssociationGame.js";

// INITIALIZE
// Create the jsPsych instance with general functionality
const jsPsych = initJsPsych({
  on_finish: function () {
    // DEBUG: show the collected data in json format upon experiment completion
    jsPsych.data.displayData("json");
  },
});
// Start experiment with an empty timeline (i.e., procedure)
const timeline = [];

timeline.push({
  type: jsPsychWordAssociationGame,
  stimulus: "test",
});

jsPsych.run(timeline);

jsPsychWordAssociationGame.js (custom plugin; used the .js template available on jspsych-contrib)

import { jsPsychModule } from "jspsych";
// npm install kaboom@next
import kaboom from "kaboom";

export var jsPsychWordAssociationGame = (function (jspsych) {
  "use strict";

  // INPUT PARAMETERS
  const info = {
    name: "jsPsychWordAssociationGame",
    parameters: {
      // TARGET
      stimulus: {
        type: jspsych.ParameterType.STRING,
        default: "Testing",
      },

      // ANSWER OPTIONS
      answer_type: {
        type: jspsych.ParameterType.STRING,
        default: "OPEN", // Choices: [OPEN, MC (not yet implemented)]
      },
      // GAME SIZE
      canvas_size: {
        type: jspsych.ParameterType.INT,
        array: true,
        default: [150, 150],
      },
    },
  };

  class jsPsychKaboom {
    constructor(jsPsych) {
      this.jsPsych = jsPsych;
    }
    trial(display_element, trial) {
      // data saving
      var trial_data = {
        score: 0,
      };

      // Initialize Target Canvas
      display_element.innerHTML =
        '<div id="jspsych-canvas-container">' +
        '<canvas id="jspsych-canvas-kaboom"></canvas>' +
        "</div>";

      // Initialize game screen.
      kaboom({
        width: trial.canvas_size[0],
        height: trial.canvas_size[1],
        font: "sans-serif",
        canvas: document.querySelector("#jspsych-canvas-kaboom"),
        background: [204, 255, 204],
      });

      // DEBUGGING
      debug.inspect = true;

      // Create 'ground'
      const ground = add([
        rect(width(), 10),
        outline(4),
        area(),
        pos(0, height() - 10),
        body({ isStatic: true }),
      ]);

      // Add target word
      const target_stimulus = add([
        text("TARGET"),
        pos(center()),
        color(255, 255, 255),
        body(),
        area(),
        move(DOWN, 150),
      ]);

      target_stimulus.onCollide(() => {
        this.jsPsych.finishTrial(trial_data);
      });

      onKeyPress("space", () => {
        if (trial_data.score < trial.max_score) {
          // Increment score by 1
          trial_data.score += 1;
          console.log(trial_data);
        } else {
          // end trial
          this.jsPsych.finishTrial(trial_data);
        }
      });
    }
  }
  jsPsychKaboom.info = info;

  return jsPsychKaboom;
})(jsPsychModule);

I first had an issue with the variable jsPsychWordAssociationGame not being found, which is why I added the export. I then had an issue with the jsPsychModule not being found, for which I added the import. I’m now stuck on an error where I do not understand why it occurs: "TypeError: undefined is not an object (evaluating 'jspsych.ParameterType’)”. I added defaults to all input parameters to prevent this, but it has not solved the issue.

Would love any pointers on how to get a custom plugin to work in my Parcel / npm development setup. At some point in time I got the plugin to work when I used CDN urls rather than npm, but couldn’t tell you what I did then.

Thanks in advance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant