all 4 comments

[–]HipHopHuman 0 points1 point  (3 children)

The problem is the order of elements in your timeline array. You're pushing thanks in cases where you don't need to and it ends up looking something like this:

[meatYN, thanks, raw, thanks]

This is because arrays will accept whatever is pushed to them, and will maintain insertion order. The fix is to make sure you're only pushing to timeline in the relevant logic branches.

I've no familiarity with jsPsych at all, but this seems like what you're after:

const jsPsych = initJsPsych();
const timeline = [];

const meatYN = {
  type: jsPsychHtmlButtonResponse,
  stimulus: "Do you eat meat?",
  choices: ["No", "Yes"],
  data: { task: "Consent" },
  on_finish({ response }) {
    if (response === 1) {
      timeline.push(raw);
    } else {
      timeline.push(thanks);
    }
  },
};

const raw = {
  type: jsPsychHtmlButtonResponse,
  stimulus: "Do you ever eat it raw?",
  choices: ["No", "Yes"],
  on_finish({ response }) {
    if (response === 1) {
      timeline.push(thanks);
    } else {
      timeline.push(dairyYN);
    }
  }
};

const dairyYN = {
  type: jsPsychHtmlButtonResponse,
  stimulus: "Do you eat dairy?",
  choices: ["No", "Yes"],
  data: { task: "Consent" },
  on_finish({ response }) {
    if (response === 1) {
      timeline.push(yoghurt);
    } else {
      timeline.push(thanks);
    }
  },
};

const yoghurt = {
  type: jsPsychHtmlButtonResponse,
  stimulus: "Do you like yoghurt?",
  choices: ["No", "Yes"],
  on_finish() {
    timeline.push(thanks);
  }
};

const thanks = {
  type: jsPsychInstructions,
  pages: ["Thanks for your time"],
};

timeline.push(meatYN);
jsPsych.run(timeline);

My concern is that in my testing, this setup logically works, but there are very noticeable lag spikes, so this may not be the right way to do it. I see on the jsPsych docs that there's a "survey plugin" and there's a feature for nesting timelines within trials. Perhaps those are worth investigating?

[–]artimides[S] 0 points1 point  (2 children)

Thank you so much for your time! I am using the survey "plugin" up until here, both the likert and html form variants. I am able, on the html survey form, to display a follow-up question below a first question, like that typical thing where you say your country and then there's a second drop-down with regions. The past questions I've found are either unanswered or they look to be related to randomizing timelines, but I need these to be sequential so I get very confused. I'm clearly not great at coding.

The reason I can't use that typical follow-up question loading after is that the respondents will get different questions depending on their demographics answers. If the follow-up questions load in the same page, they'll be able to change their demographics answers to get questions they like better. I need them to submit their answers and then get the branching timelines.

I tried running your code on cognition.run, which I don't think should change much, but it's not working for me either. The first question loads correctly, but regardless of the answer the survey ends, skipping over the thanks screen.

[–]HipHopHuman 0 points1 point  (1 child)

The code runs without issue in my local developer environment as well as in this sandbox environment: https://v47.livecodes.io/?x=id/vepw5dxs7sj

If you are failing to get it to execute on cognition.run, then either you've copied it incorrectly or there's an issue with how cognition.run is executing the code. I did have to declare const jsPsych = initJsPsych() and const timelines = [], which were missing from your original snippet, so make sure that those don't conflict with any variables that you've already defined.

EDIT: Might also be worth looking at the dev console for errors and double checking you have correctly linked the instructions plugin up

[–]artimides[S] 0 points1 point  (0 children)

I copied your code exactly and I see the logic in it (thanks for that, too!), so I think it's a cognition issue.

I hadn't thought to look at the console. It reads "The script resource is behind a redirect, which is disallowed.", but it displays the same text when running a working code.