Hi Community!
I write a Javascript to present a web page of a simulated social media, and capture participants engagement of that web page(comment, share, like….).
Everything works well (we ran a successful version in prolific before), but after some twist in the style of the survey, there is an error pop up when click the next page. (I just fixed the next page button problem, now the button occurs, but when I try to click it, there is an error)

Below is the JS I used:
Qualtrics.SurveyEngine.addOnload(function () {
var that = this;
// —— Utility function: safely write into JS Embedded Data
function setJS(key, val) {
try {
Qualtrics.SurveyEngine.setJSEmbeddedData(key, val);
} catch (e) {
console.error("setJSEmbeddedData failed:", key, e);
}
}
// —— A) Outer Toast utility (disabled: no prompt will be shown)
var FFToast = { show: function(){} };
function toastOnce(){ /* no-op: disable all toast */ }
// —— 1) Participant ID
var pid = Qualtrics.SurveyEngine.getEmbeddedData('ProlificPID')
|| Qualtrics.SurveyEngine.getEmbeddedData('WorkerId')
|| Qualtrics.SurveyEngine.getEmbeddedData('ResponseID');
// —— 2) iframe
var iframe = document.createElement('iframe');
iframe.src = 'https://claireyuqingyang.github.io/JPPM_Pilot_All_v3/?pid=' + encodeURIComponent(pid || '');
iframe.style.width = '100%';
iframe.style.height = '650px';
iframe.style.border = '0';
this.getQuestionTextContainer().innerHTML = '';
this.getQuestionTextContainer().appendChild(iframe);
// —— 3) MONITOR CHILD PAGE
var logs = a];
var lastSavedLen = 0;
window.addEventListener('message', function (e) {
var msg = e.data;
if (!msg) return;
if (msg.type === 'ff_log') {
logs.push(msg);
if (msg.action === 'send_comment') {
// Previously this would call toastOnce('...'), now toastOnce is no-op, so no prompt will show
toastOnce('Your comment has been sent.');
}
} else if (msg.type === 'ff_log_bulk' && Array.isArray(msg.payload)) {
var seen = new Set(logs.map(x => (x.ts || '') + '|' + (x.action || '')));
msg.payload.forEach(ev => {
var k = (ev.ts || '') + '|' + (ev.action || '');
if (!seen.has(k)) { logs.push(ev); seen.add(k); }
});
if (msg.payload.some(ev => ev && ev.action === 'send_comment')) {
// Same here, no prompt will show
toastOnce('Your comment has been sent.');
}
}
});
// —— 4) CHILD PAGE dump
function requestDump() {
try { iframe.contentWindow.postMessage({ type: 'ff_request_dump' }, '*'); } catch (e) {}
}
// —— 5) WRITE IN Embedded Data
function saveToEmbedded(reason) {
try {
var compact = logs.map(function(ev) {
var a = ev.action || '';
var d = ev.detail || {};
var rec = {
a: a,
id: d.tweetId || null,
ts: ev.ts || null
};
if ('active' in d) rec.active = !!d.active;
if (a === 'send_comment') {
rec.comment = (d.comment || '').slice(0, 4000);
}
return rec;
});
var json = JSON.stringify({
pid: pid || null,
reason: reason || 'autosave',
t: new Date().toISOString(),
count: compact.length,
actions: compact
});
var CHUNK = 19000;
var i = 1, off = 0;
while (off < json.length) {
setJS('ff_log_json_' + i, json.slice(off, off + CHUNK));
i++; off += CHUNK;
}
var n = i - 1;
setJS('ff_log_json_n', n);
setJS('ff_log_json_len', json.length);
setJS('ff_log_last_saved_ts', new Date().toISOString());
setJS('ff_saved_reason', reason);
setJS('ff_saved_count', String(compact.length));
setJS('ff_saved_at', new Date().toISOString());
lastSavedLen = logs.length;
} catch (e) {
setJS('ff_error', 'save:' + (e && e.message || e));
}
}
// —— 6) request dump first
function requestThenSave(reason) {
requestDump();
setTimeout(function () { saveToEmbedded(reason); }, 200);
}
// Next button
var nextBtn = this.getNextButton && this.getNextButton();
if (nextBtn) {
nextBtn.addEventListener('click', function () {
requestThenSave('next');
}, true);
}
// pagehide & beforeunload
window.addEventListener('pagehide', function () { requestThenSave('pagehide'); });
window.addEventListener('beforeunload', function () { requestThenSave('beforeunload'); });
// —— 7) Heartbeat: every 5 seconds
var autosaveTimer = setInterval(function () {
requestDump();
setTimeout(function () {
if (logs.length !== lastSavedLen) saveToEmbedded('autosave');
}, 120);
}, 5000);
document.addEventListener('visibilitychange', function(){
if (document.visibilityState === 'hidden') { try{ clearInterval(autosaveTimer);}catch(e){} }
});
});
Thank you so much!