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

Attempt to getInteractionCount on LMS that doesn't support this SCORM 1.2 feature #294

Closed
paulstevendev opened this issue Nov 6, 2023 · 8 comments · Fixed by #295
Closed
Assignees

Comments

@paulstevendev
Copy link
Contributor

I am seeing an issue on an LMS where an error dialogue is displaying after sumitting a question.

image

Looking at the code I can see it is calling this.scorm.getInteractionCount() inside the onQuestionRecordInteraction function within adapt-stateful-session.js

So it would appear this code does not have any check to see if the LMS supports cmi.interaction._count

I am getting the error every time I answer a question. It is possibly an issue with this particular LMS but it is the only LMS we use that does not have this optional SCORM 1.2 element. So it would be good to hear if anyone else has tested this on an LMS that does not support cmi.interactions._count

https://github.com/adaptlearning/adapt-contrib-spoor/blob/f07a6032a687b6653c4dbcd903797663fa3ec665/js/adapt-stateful-session.js#L205C2-L220C4

@oliverfoster
Copy link
Member

oliverfoster commented Nov 7, 2023

The quoted lines, call offlineStorage.set('interaction', id, response, result, latency, responseType); :

onQuestionRecordInteraction(questionView) {
if (!this._shouldRecordInteractions) return;
// View functions are deprecated: getResponseType, getResponse, isCorrect, getLatency
const questionModel = questionView.model;
const responseType = (questionModel.getResponseType ? questionModel.getResponseType() : questionView.getResponseType());
// If responseType doesn't contain any data, assume that the question
// component hasn't been set up for cmi.interaction tracking
if (_.isEmpty(responseType)) return;
const id = this._uniqueInteractionIds
? `${this.scorm.getInteractionCount()}-${questionModel.get('_id')}`
: questionModel.get('_id');
const response = (questionModel.getResponse ? questionModel.getResponse() : questionView.getResponse());
const result = (questionModel.isCorrect ? questionModel.isCorrect() : questionView.isCorrect());
const latency = (questionModel.getLatency ? questionModel.getLatency() : questionView.getLatency());
offlineStorage.set('interaction', id, response, result, latency, responseType);
}

Which is calling recordInteraction:

set(name, value) {
// Convert arguments to array and drop the 'name' parameter
const args = [...arguments].slice(1);
const isObject = typeof name === 'object';
if (isObject) {
value = name;
name = 'suspendData';
}
if (this.useTemporaryStore()) {
if (isObject) {
Object.assign(this.temporaryStore, value);
} else {
this.temporaryStore[name] = value;
}
return true;
}
switch (name.toLowerCase()) {
case 'interaction':
return this.scorm.recordInteraction(...args);

Which is calling isSupported, if (!this.isSupported('cmi.interactions._count')) { :

recordInteraction(id, response, correct, latency, type) {
if (!this.isSupported('cmi.interactions._count')) {
this.logger.info('ScormWrapper::recordInteraction: cmi.interactions are not supported by this LMS...');
return;
}
switch (type) {
case 'choice':
this.recordInteractionMultipleChoice.apply(this, arguments);
break;
case 'matching':
this.recordInteractionMatching.apply(this, arguments);
break;
case 'numeric':
this.isSCORM2004() ? this.recordInteractionScorm2004.apply(this, arguments) : this.recordInteractionScorm12.apply(this, arguments);
break;
case 'fill-in':
this.recordInteractionFillIn.apply(this, arguments);
break;
default:
console.error(`ScormWrapper.recordInteraction: unknown interaction type of '${type}' encountered...`);
}
}

isSupported calls get:

isSupported(property) {
this.logger.debug(`ScormWrapper::isSupported: _property=${property}`);
if (this.finishCalled) {
this.logger.debug('ScormWrapper::isSupported: ignoring request as \'finish\' has been called');
return;
}
if (!this.lmsConnected) {
this.handleConnectionError();
return false;
}
this.scorm.get(property);
return (this.scorm.debug.getCode() !== 401); // 401 is the 'not implemented' error code
}

getValue is called here:

pipwerks.SCORM.data.get = function(parameter) {
var value = null,
scorm = pipwerks.SCORM,
trace = pipwerks.UTILS.trace,
debug = scorm.debug,
traceMsgPrefix = "SCORM.data.get('" + parameter + "') ";
if (scorm.connection.isActive) {
var API = scorm.API.getHandle(),
errorCode = 0;
if (API) {
switch (scorm.version) {
case "1.2":
value = API.LMSGetValue(parameter);
break;
case "2004":
value = API.GetValue(parameter);
break;
}

Your error is triggering here:

getValue(property) {
this.logger.debug(`ScormWrapper::getValue: _property=${property}`);
if (this.finishCalled) {
this.logger.debug('ScormWrapper::getValue: ignoring request as \'finish\' has been called');
return;
}
if (!this.lmsConnected) {
this.handleConnectionError();
return;
}
const value = this.scorm.get(property);
const errorCode = this.scorm.debug.getCode();
switch (errorCode) {
case 0:
break;
case 403:
// 403 errors are common (and normal) when targetting SCORM 2004 - they are triggered on any
// attempt to get the value of a data model element that hasn't yet been assigned a value.
this.logger.warn('ScormWrapper::getValue: data model element not initialized');
break;
default:
this.handleDataError(new ScormError(CLIENT_COULD_NOT_GET_PROPERTY, {

This is your error:

CLIENT_COULD_NOT_GET_PROPERTY: 'Unable to get the value of {{property}} from the Learning Management System\n\nError: {{errorCode}} - {{{errorInfo}}}\nLMS Error Info: {{{diagnosticInfo}}}',

So it is checking, but the check pushes an error to the dialogue.

This is where the dialogue is shown:

if (!this.suppressErrors && (!this.logOutputWin || this.logOutputWin.closed) && confirm(`${messages.title}:\n\n${message}\n\n${messages.pressOk}`)) {
this.showDebugWindow();
}

It can be controlled with:

"_suppressErrors": false,

However, it does seem a bit odd. isSupported shouldn't really display an error if the value isn't supported.

@danielghost any thoughts?

@paulstevendev
Copy link
Contributor Author

paulstevendev commented Nov 7, 2023

Surely this code is not checking isSupported('cmi.interactions._count')

https://github.com/adaptlearning/adapt-contrib-spoor/blob/f07a6032a687b6653c4dbcd903797663fa3ec665/js/adapt-stateful-session.js#L213C1-L215C34

const id = this._uniqueInteractionIds ?${this.scorm.getInteractionCount()}-${questionModel.get('_id')} : questionModel.get('_id');

@oliverfoster
Copy link
Member

oliverfoster commented Nov 7, 2023

Yup, agreed. Needs an if (!this.scorm.isSupported('cmi.interactions._count')) return; above that line?

@paulstevendev
Copy link
Contributor Author

That is exactly what I have done and testing as we speak

@paulstevendev
Copy link
Contributor Author

@oliverfoster happy to create a PR for this.

Not done this before so just checking the procedure

Do I create a local branch issue/294 and then push this up (I don't appear to have permission to do so)

Then create a PR

@oliverfoster
Copy link
Member

oliverfoster commented Nov 7, 2023

You can fork the repo, create your issue/294 and then pr from there.

@paulstevendev
Copy link
Contributor Author

Done

@oliverfoster oliverfoster moved this from Assigned to Needs Reviewing in adapt_framework: The TODO Board Nov 7, 2023
oliverfoster pushed a commit that referenced this issue Nov 15, 2023
@github-project-automation github-project-automation bot moved this from Needs Reviewing to Recently Released in adapt_framework: The TODO Board Nov 15, 2023
github-actions bot pushed a commit that referenced this issue Nov 15, 2023
## [5.9.2](v5.9.1...v5.9.2) (2023-11-15)

### Fix

* Check LMS supports cmi.interactions._count (fixes #294) (#295) ([d73c7e4](d73c7e4)), closes [#294](#294) [#295](#295)
Copy link

🎉 This issue has been resolved in version 5.9.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

github-actions bot pushed a commit to nagyist/adapt-contrib-spoor that referenced this issue Mar 19, 2024
# [2.2.0](v2.1.3...v2.2.0) (2024-03-19)

### Bug

* score logic (adaptlearning#267) ([898fa80](898fa80)), closes [adaptlearning#267](https://github.com/nagyist/adapt-contrib-spoor/issues/267)

### chore

* added package.json (adaptlearning#214) ([c940daf](c940daf)), closes [adaptlearning#214](https://github.com/nagyist/adapt-contrib-spoor/issues/214) [#3072](https://github.com/nagyist/adapt-contrib-spoor/issues/3072)

### Chore

* Readme updates for broken links, clarity, and linting errors (fixes adaptlearning#312) (adaptlearning#313) ([df90b8d](df90b8d)), closes [adaptlearning#312](https://github.com/nagyist/adapt-contrib-spoor/issues/312) [adaptlearning#313](https://github.com/nagyist/adapt-contrib-spoor/issues/313)

### fix

* Adding a pagehide listener to cover bases when unload becomes deprecated (adaptlearning#298) ([177de84](177de84)), closes [adaptlearning#298](https://github.com/nagyist/adapt-contrib-spoor/issues/298)

### Fix

* Add SCORM version selector to config JSON schema (fixes adaptlearning#249) ([a824a72](a824a72)), closes [adaptlearning#249](https://github.com/nagyist/adapt-contrib-spoor/issues/249)
* Added gitignore for release automation (adaptlearning#244) ([27decdb](27decdb)), closes [adaptlearning#244](https://github.com/nagyist/adapt-contrib-spoor/issues/244)
* Added release automation (adaptlearning#240) ([d2b21a4](d2b21a4)), closes [adaptlearning#240](https://github.com/nagyist/adapt-contrib-spoor/issues/240)
* Amend to default schema value for `_setCompletedWhenFailed` (fixes adaptlearning#256) (adaptlearning#258) ([cf29cb1](cf29cb1)), closes [adaptlearning#256](https://github.com/nagyist/adapt-contrib-spoor/issues/256) [adaptlearning#258](https://github.com/nagyist/adapt-contrib-spoor/issues/258)
* Amended logic to check for supported `_children` elements before attempting to set values (adaptlearning#306) ([4dddbee](4dddbee)), closes [adaptlearning#306](https://github.com/nagyist/adapt-contrib-spoor/issues/306)
* Bump http-cache-semantics from 4.1.0 to 4.1.1 (adaptlearning#263) ([aa3e7f4](aa3e7f4)), closes [adaptlearning#263](https://github.com/nagyist/adapt-contrib-spoor/issues/263)
* Changed logic for 401 error handling (adaptlearning#303) ([a71d7a0](a71d7a0)), closes [adaptlearning#303](https://github.com/nagyist/adapt-contrib-spoor/issues/303)
* Check LMS supports cmi.interactions._count (fixes adaptlearning#294) (adaptlearning#295) ([d73c7e4](d73c7e4)), closes [adaptlearning#294](https://github.com/nagyist/adapt-contrib-spoor/issues/294) [adaptlearning#295](https://github.com/nagyist/adapt-contrib-spoor/issues/295)
* Close loading screen via router.hideLoading() (fixes adaptlearning#291) (adaptlearning#292) ([0fe5539](0fe5539)), closes [adaptlearning#291](https://github.com/nagyist/adapt-contrib-spoor/issues/291) [adaptlearning#292](https://github.com/nagyist/adapt-contrib-spoor/issues/292)
* Correct printCompletionInformation string creation ([9e07fbf](9e07fbf))
* delay error messaging until all course data is ready (adaptlearning#301) ([62a2f30](62a2f30)), closes [adaptlearning#301](https://github.com/nagyist/adapt-contrib-spoor/issues/301)
* Dynamic course folders (fixes adaptlearning#264) (adaptlearning#265) ([a0b8813](a0b8813)), closes [adaptlearning#264](https://github.com/nagyist/adapt-contrib-spoor/issues/264) [adaptlearning#265](https://github.com/nagyist/adapt-contrib-spoor/issues/265)
* Ensure cmi.interactions.n.id is unique (fixes adaptlearning#234) (adaptlearning#246) ([ad5380a](ad5380a)), closes [adaptlearning#234](https://github.com/nagyist/adapt-contrib-spoor/issues/234) [adaptlearning#246](https://github.com/nagyist/adapt-contrib-spoor/issues/246) [adaptlearning#234](https://github.com/nagyist/adapt-contrib-spoor/issues/234) [adaptlearning#246](https://github.com/nagyist/adapt-contrib-spoor/issues/246)
* error logging order to match call execution (fixes adaptlearning#307). (adaptlearning#308) ([ea190bf](ea190bf)), closes [adaptlearning#307](https://github.com/nagyist/adapt-contrib-spoor/issues/307) [adaptlearning#308](https://github.com/nagyist/adapt-contrib-spoor/issues/308)
* escaped double quotes in _setCompletedWhenFailed help msg (fixes adaptlearning#254) ([333b58c](333b58c)), closes [adaptlearning#254](https://github.com/nagyist/adapt-contrib-spoor/issues/254)
* LZMAFactory error when Web Workers are not implemented - fixes adaptlearning#253. (adaptlearning#255) ([b790967](b790967)), closes [adaptlearning#253](https://github.com/nagyist/adapt-contrib-spoor/issues/253) [adaptlearning#255](https://github.com/nagyist/adapt-contrib-spoor/issues/255)
* Release job now uses v3 for checkout and setup-node actions ([0e3743d](0e3743d))
* Reworked and removed offline_API_wrapper.js (fixes adaptlearning#260) (adaptlearning#261) ([75f15a6](75f15a6)), closes [adaptlearning#260](https://github.com/nagyist/adapt-contrib-spoor/issues/260) [adaptlearning#261](https://github.com/nagyist/adapt-contrib-spoor/issues/261)
* Score logic ([c0d5a62](c0d5a62))
* set html lang and dir attributes from config.json (fixes #499) (adaptlearning#310) ([2642a5a](2642a5a)), closes [#499](https://github.com/nagyist/adapt-contrib-spoor/issues/499) [adaptlearning#310](https://github.com/nagyist/adapt-contrib-spoor/issues/310)
* Undefined settings error (adaptlearning#275) ([791c436](791c436)), closes [adaptlearning#275](https://github.com/nagyist/adapt-contrib-spoor/issues/275)
* version bump for pull 125 ([608e79f](608e79f))
* Version numbers removed from Readme files ([9f43ba6](9f43ba6))
* Version patch bump (adaptlearning#290) ([f801969](f801969)), closes [adaptlearning#290](https://github.com/nagyist/adapt-contrib-spoor/issues/290)
* wrapper.js & adapt-contrib-spoor updated to work with Jest testing. (fixes adaptlearning#284) (adaptlearning#285) ([cb3d93f](cb3d93f)), closes [adaptlearning#284](https://github.com/nagyist/adapt-contrib-spoor/issues/284) [adaptlearning#285](https://github.com/nagyist/adapt-contrib-spoor/issues/285)

### New

* Added _uniqueInteractionIds, testing support for cmi.interactions (adaptlearning#278) ([f88877c](f88877c)), closes [adaptlearning#278](https://github.com/nagyist/adapt-contrib-spoor/issues/278)
* Added `cmi.objectives` support (fixes adaptlearning#279). (adaptlearning#280) ([cf911c5](cf911c5)), closes [adaptlearning#279](https://github.com/nagyist/adapt-contrib-spoor/issues/279) [adaptlearning#280](https://github.com/nagyist/adapt-contrib-spoor/issues/280)
* Added ability to compile as SCORM 1.2 or SCORM 2004 (fixes adaptlearning#249) ([497637a](497637a)), closes [adaptlearning#249](https://github.com/nagyist/adapt-contrib-spoor/issues/249)
* Added ability to configure `_setCompletedWhenFailed` - fixes adaptlearning#242. (adaptlearning#251) ([f3a7b7a](f3a7b7a)), closes [adaptlearning#242](https://github.com/nagyist/adapt-contrib-spoor/issues/242) [adaptlearning#251](https://github.com/nagyist/adapt-contrib-spoor/issues/251)
* Improve use of scorm_test_harness.html (fixes adaptlearning#247) (adaptlearning#248) ([479c2d1](479c2d1)), closes [adaptlearning#247](https://github.com/nagyist/adapt-contrib-spoor/issues/247) [adaptlearning#248](https://github.com/nagyist/adapt-contrib-spoor/issues/248)
* Issue and pr project addition automation (refs adaptlearning/adapt_framework#3315) (adaptlearning#239) ([578f9b0](578f9b0)), closes [adaptlearning#239](https://github.com/nagyist/adapt-contrib-spoor/issues/239)
* network connection test (adaptlearning#270) ([ec5ef8a](ec5ef8a)), closes [adaptlearning#270](https://github.com/nagyist/adapt-contrib-spoor/issues/270)

### Update

* Added a new maxCharLimitOverride property to allow override o… (adaptlearning#287) ([68e7064](68e7064)), closes [adaptlearning#287](https://github.com/nagyist/adapt-contrib-spoor/issues/287)

### Upgrade

* Bump ip from 1.1.8 to 1.1.9 (adaptlearning#311) ([1728659](1728659)), closes [adaptlearning#311](https://github.com/nagyist/adapt-contrib-spoor/issues/311)
* Bump yaml and semantic-release (adaptlearning#276) ([9a46faa](9a46faa)), closes [adaptlearning#276](https://github.com/nagyist/adapt-contrib-spoor/issues/276)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants