google-apps-scriptgoogle-sheetsgoogle-formsgoogle-form-quiz

How to use a for loop with .createChoice in Google Apps Script to create a quiz from a sheet?


I am using Google Apps Script to generate Google Forms from a Sheet. Questions are in rows and question choices are in columns.

enter image description here Here is a link to the Google sheet if needed.

It is a straightforward task when using .setChoiceValues(values)

if (questionType == 'CHOICE') {
  var choicesForQuestion = [];
  for (var j = 4; j < numberColumns; j++)
    if (data[i][j] != "")
      choicesForQuestion.push(data[i][j]);

  form.addMultipleChoiceItem()
    .setChoiceValues(choicesForQuestion);
}

However, when I try to use .createChoice(value, isCorrect), the parameters call for value to be a string and isCorrect to be Boolean.

An example without a loop looks like this:

  var item = FormApp.getActiveForm().addCheckboxItem();
  item.setTitle(data[3][1]);
  // Set options and correct answers
  item.setChoices([
    item.createChoice("chocolate", true),
    item.createChoice("vanilla", true),
    item.createChoice("rum raisin", false),
    item.createChoice("strawberry", true),
    item.createChoice("mint", false)
  ]);

I can not figure out how to add the loop. After reading over other posts, I have tried the following:

if (questionType == 'CHOICE') {
  var questionInfo = [];
  for (var j = optionsCol; j < maxOptions + 1; j++)
    if (data[i][j] != "")
      questionInfo.push( form.createChoice(data[i][j], data[i][j + maxOptions]) );

    form.addMultipleChoiceItem()
      .setChoices(questionInfo);
  }

optionsCol is the first column of questions options maxOptions is how many options are allowed by the sheet (currently 5). The isCorrect information is 5 columns to the right.

However, this not working because the array questionsInfo is empty.

What is the best way to do this?


Solution

  • Probably your issue is related to the method you reference--Form#createChoice--not existing. You need to call MultipleChoiceItem#createChoice, by first creating the item:

    /**
     * @param {Form} formObj the Google Form Quiz being created
     * @param {any[]} data a 1-D array of data for configuring a multiple-choice quiz question
     * @param {number} index The index into `data` that specifies the first choice
     * @param {number} numChoices The maximum possible number of choices for the new item
     */ 
    function addMCItemToForm_(formObj, data, index, numChoices) {
      if (!formObj || !data || !Array.isArray(data)
          || Array.isArray(data[0]) || data.length < (index + 2 * numChoices))
      {
        console.error({message: "Bad args given", hasForm: !!formObj, info: data,
            optionIndex: index, numChoices: numChoices});
        throw new Error("Bad arguments given to `addMCItemToForm_` (view on StackDriver)");
      }
      const title = data[1];
    
      // Shallow-copy the desired half-open interval [index, index + numChoices).
      const choices = data.slice(index, index + numChoices);
      // Shallow-copy the associated true/false data.
      const correctness = data.slice(index + numChoices, index + 2 * numChoices);
      const hasAtLeastOneChoice = choices.some(function (c, i) {
        return (c && typeof correctness[i] === 'boolean');
      });
      if (hasAtLeastOneChoice) {
        const mc = formObj.addMultipleChoiceItem().setTitle(title);
    
        // Remove empty/unspecified choices.
        while (choices[choices.length - 1] === "") {
          choices.pop();
        }
        // Convert to choices for this specific MultipleChoiceItem.
        mc.setChoices(choices.map(function (choice, i) {
          return mc.createChoice(choice, correctness[i]);
        });
      } else {
        console.warn({message: "Skipped bad mc-item inputs", config: data, 
            choices: choices, correctness: correctness});
      }
    }
    

    You would use the above function as described by its JSDoc - pass it a Google Form object instance to create the quiz item in, an array of the details for the question, and the description of the location of choice information within the details array. For example:

    function foo() {
      const form = FormApp.openById("some id");
      const data = SpreadsheetApp.getActive().getSheetByName("Form Initializer")
        .getSheetValues(/*row*/, /*col*/, /*numRows*/, /*numCols*/);
    
      data.forEach(function (row) {
        var qType = row[0];
        ...
        if (qType === "CHOICE") {
          addMCItemToForm_(form, row, optionColumn, numOptions);
        } else if (qType === ...
        ...
    }
    

    References