fix for 'cmi.interactions_0 is undefined' bug in scorm 1.2 (and other 'is undefined' bugs).

fix for 'cmi.interactions_0 is undefined' bug in scorm 1.2 (and other 'is undefined' bugs).

by tim st.clair -
Number of replies: 1
Picture of Particularly helpful Moodlers Picture of Plugin developers

I've recently been trying to use cmi.interactions.n to record data about a learner interaction (in a same-domain iframe within the content). this works on the first save. if I suspend and come back to the sco, or if I navigate internally away from the page that contais the interaction, the come back, it tries to internally call LMSInitialise() again, which then crashes out with an error within initalisation from the /mod/scorm/datamodels/scorm_12.js file. PHP is passing in new data based on the interactions/objectives that are now stored.

In the tracker, there is bug https://moodle.atlassian.net/browse/MDL-51769 from 2015. The 'proposed solution' which just throws a try-catch around the line was done in mid 2018 - the coding equivalent of looking the other way. But the bug is still present and untouched here in moodle 5.1 in 2026. The most recent comment seems to sum it up - effectively "Scorm sucks and I've got better things to do".

I can't add anything in tracker. I get logged out of tracker just for trying to vote an issue, or if my rural internet drops out again. I'm trying to patch it in my moodle fork and do a pull request, but I can't figure that out either. I'd look at the documentation, but it all now redirects back to 'page not found' pages on moodledev.io. super.

ANYWAY

The actual error being thrown is 'TypeError: cmi.interactions_0 is undefined'. The code in this file is hard to understand because it's all done with javascript eval() statements, which turn strings into code in the current context. I guess in the ancient times of ES2 and ES3 that sort of thing was all you had, and the scorm 1.2 code is from back then.

If I look at the code flow it's roughly:

  1. create new Objects for base elements like cmi.interactions.
  2. Loop through the datamodel and look for default values to apply for object collections.
  3. Initialise the object collections.
        for (element in datamodel[scoid]) {
            if (element.match(/\.n\./) == null) {
                if (typeof datamodel[scoid][element].defaultvalue != 'undefined') {
                    eval(element + ' = datamodel["' + scoid + '"]["' + element + '"].defaultvalue;');
                } else {
                    eval(element + ' = "";');
                }
            }
        }

        eval(cmiobj[scoid]);
        eval(cmiint[scoid]);

What do those last two eval's do? Well, cmiint[scoid] is actually a string containing things like cmi.interactions.objectives = new Object(). The code that initialises the objects, which is passed in to the scorm function from php.

This is The Fix. No try-catch needed. Just make sure things exist before you try looping over them. 

        eval(cmiobj[scoid]);
        eval(cmiint[scoid]);

        for (element in datamodel[scoid]) {
            if (element.match(/\.n\./) == null) {
                if (typeof datamodel[scoid][element].defaultvalue != 'undefined') {
                    eval(element + ' = datamodel["' + scoid + '"]["' + element + '"].defaultvalue;');
                } else {
                    eval(element + ' = "";');
                }
            }
        }

I've had to apply a customscript to my site just to modify the /mod/scorm/player.php to point to my updated scorm_12.js file just to apply this in a way that it doesn't undo the next moodle update. this is not a long-term solution, since customscripts have become a bit janky since the file restructuring. perhaps there's a local-plugin way to override a requirejs script when it requests a particular file, but I don't know what it is and there's no developer documentation about it.

Average of ratings: -
In reply to tim st.clair

fix for 'cmi.interactions_0 is undefined' bug in scorm 1.2 (and other 'is undefined' bugs).

by Dan Marsden -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Plugins guardians Picture of Testers Picture of Translators
brings back memories.... smile

probably the biggest barrier is that any PR that touches an existing eval() call is likely to trigger a review process saying "we should not be using eval in that way..." and then of course that opens a much bigger can...
Average of ratings: Useful (1)