Upgrades.js Explanation


I'm hoping someone won't mind casting a quick eye over the below to check it will do what I think it will do? The explanation for upgrades.js aren't very thorough...

for major version 1 minor 12, I need to:

1. for each question (parameters.categoriesList.questionList) I need to add an image field, and a textAnswerPoints field,

2. If questionType is multipleChoice, add a multipleChoicePoints field to each of the alternative answers.

3. Add a back button enabled boolean field to each category.

Will this code do that?

var H5PUpgrades = H5PUpgrades || {};
H5PUpgrades['H5P.FTAQuestionnaire'] = (function () {
  return {
    1: {
      12: function (parameters, finished) {
        if (parameters && parameters.categoriesList) {
          parameters.categoriesList.forEach(function (category) {
            if (category.questionList !== undefined) {
              category.questionList.forEach(function (question) {
                if (question.textAnswerPoints === undefined) {
                  question.textAnswerPoints = 0;
                if (question.image === undefined) {
                  question.image = {};
                question.image.path = '';
                question.image.width = 0;
                question.image.mime = '';
                question.image.height = 0;
                question.image.copyright = {};
                question.image.copyright.licence = '';
                if (question.questionType === 'multipleChoice' ) {
                  question.multipleChoiceInputGroup.alternatives.multipleChoicePoints = 0;
              if (category.disableBackButton === undefined) {
                category.disableBackButton = false;
        finished(null, parameters);


otacke's picture


This might be a dumb question, but if you have that function already, why don't you let it run on some content and check if it leads to the result that you expect?

Without knowing what your semantics.json looks like:

  • `parameters.categoriesList[].category.questionList[].question.textAnswerPoints` will be set to 0 if that value is not set yet (but this would only be necessary if you turned the textAnswerPoints into a mandatory value - your content type can simply sanitize the value anyway)
  • `parameters.categoriesList[].category.questionList[].question.image` will be set with dummy image values, but this should also be necessary if the image became mandatory. `licence` is misspelled (it's `license`) and it cannot be an empty string - and the other default values also feel odd.
  • The other two could be okay, but I'd not be sure why they would need to be mandatory in the editor. Hard to say without actually knowing what this is for.


I just didn't want to break anything.

So it seems that you're saying that only items marked 'required' in semantics need to be in this upgrades.js file? Or being moved around or deleted from the semantics I assume? I.e., If I'm adding a field for an image which is not required I leave it out of upgrades.js, or create an empty object?

otacke's picture

Not sure what you could break - you hopefully do not develop on a production site :-)

Technically, there's no hard rule that ties the "required" flag to upgrade.js. But yes, if you add a field for an image for instance and it's not mandatory, there's no reason to add it to upgrade.js at all. And even if it was mandatory (after your changes), your content type should handle this anyway. No. missing value in the parameters should make ir crash (the parameters will in fact be completely empty if you add a content type as subcontent in the Course Presentation editor, for instance).

You'd want to avoid the need to use upgrade.js, because it comes with a bump in the minor/major version which in turn means the user needs to manually upgrade existing content, dependencies in other content types may need updating, etc.

Upgrade.js is useful and must be used if you move fields out of their current context or if you need to change some value in existing parameters, it should be used to delete values that have become obsolete (although they don't break anything).