Search code examples
javascriptgoogle-apps-scriptecmascript-6google-formsgoogle-apps-script-editor

Collect responses and make stats in Google Forms with ECMAScript6


I'm collecting survey results in a Google Form using the Script Editor. My script looks like:

function myFunction() {
  var formResponses = FormApp.getActiveForm().getResponses();
  var allResponses=[];
  for (var j = 0; j < formResponses.length; j++) {
    var formResponse = formResponses[j];
    var itemResponses = formResponse.getItemResponses();
    for (var i = 0; i < itemResponses.length; i++) {
      var itemResponse = itemResponses[i];
      allResponses.push( itemResponse.getResponse() );
    }
  }
  var jsonRes=JSON.stringify(allResponses);
  MailApp.sendEmail("noreply@mydomain.com", "Survey Results", jsonRes);
}

This works just fine. Now I would like to add some stats, like calculating the number of results for each response. For that I was like to use ECMA6 Map in a simple way like:

// flatten the array 
var words=allResponses.map(a => a.join(',')).join(',').split(',')
// map reduce and calculate occurrences of the map keys
var chart=[...words.reduce( (m, v) => m.set(v, (m.get(v) || 0) + 1), new Map() )].sort((a,b) => b[1]-a[1])
chart=chart.map(function(i) { return i.join(",")})
chart=chart.map(function(item,index) { return ((index+1)+","+item)})
var jsonRes=JSON.stringify(chart);

This will just output my responses list like

[
"1,responseA,1024",
"2,responseA,956",
"3,responseA,433"
]

etc.

Unexpectedly this will cause an error into the Google Script Editor, so I though it was the ECMA6 arrow operator, so I have moved back to function:

var words=allResponses.map(function(a) { return a.join(',') } ).join(',').split(',');
  var map=words.reduce(function(m,v) { return m.set(v, (m.get(v) || 0) + 1)}, new Map() );
  // convert back Map entries to Array
  var chart = Array.from(map.entries());
  chart.sort(function(a,b){ return (b[1]-a[1])});
  var jsonRes=JSON.stringify(chart);

Funny story: The Map object is undefined ergo Google Script does not support ECMAScript6 or I'm doing something wrong, do I?

[UPDATE]

This is the working Google Script solution thanks to the response below:

function myFunction() {
  var formResponses = FormApp.getActiveForm().getResponses();
  var allResponses=[];
  for (var j = 0; j < formResponses.length; j++) {
    var formResponse = formResponses[j];
    var itemResponses = formResponse.getItemResponses();
    for (var i = 0; i < itemResponses.length; i++) {
      var itemResponse = itemResponses[i];
      allResponses.push( itemResponse.getResponse() );
    }
  }

  var words=allResponses.map(function(a) { return a.join(',') }).join(',').split(',');
  var chart = words.reduce(function(m,v) {m[v] = m[v] ? m[v] + 1 : 1; return m;}, {}); // Added
  chart = Object.keys(chart).map(function(k) {return [k, chart[k]]}).sort(function(a,b) {return b[1]-a[1]}); // Added
  chart=chart.map(function(i) { return i.join(",")})
  chart=chart.map(function(item,index) { return ((index+1)+","+item)})
  var jsonRes=JSON.stringify(chart);

  MailApp.sendEmail("noreply@mydomain.com", "Survey Results", jsonRes);
}

Solution

  • How about this sample? Google Apps Script cannot use ECMAScript6 yet. So Map.prototype.set() and Map.prototype.get() also cannot be used. I modified your script to be able to use at Google Apps Script. The modified script works at GAS.

    From :

    var chart=[...words.reduce( (m, v) => m.set(v, (m.get(v) || 0) + 1), new Map() )].sort((a,b) => b[1]-a[1])
    chart=chart.map(function(i) { return i.join(",")})
    chart=chart.map(function(item,index) { return ((index+1)+","+item)})
    var jsonRes=JSON.stringify(chart);
    

    To :

    var chart = words.reduce(function(m,v) {m[v] = m[v] ? m[v] + 1 : 1; return m;}, {}); // Added
    chart = Object.keys(chart).map(function(k) {return [k, chart[k]]}).sort(function(a,b) {return b[1]-a[1]}); // Added
    chart=chart.map(function(i) { return i.join(",")})
    chart=chart.map(function(item,index) { return ((index+1)+","+item)})
    var jsonRes=JSON.stringify(chart);
    

    jsfiddle sample

    I don't know whether this is the best modification. Since I didn't know the original data, if this was not useful for you, I'm sorry.