title: Parsing data with e.parameters
body: <p>I'm receiving the data from the JavaScript client in the format of:</p>
  <pre class="lang-golang prettyprint-override"><code>type ContactDetails struct {
      Email   string
      Subject string
      Message string
      Color1  []string
      Color2  []string
  }
  </code></pre>
  <p>The data had been sent from the <code>PostForm</code> as:</p>
  <pre class="lang-sh prettyprint-override"><code>Post from website! r.PostFrom = map[color1:[my color 1 - 1 my color 1 - 2] color2:[my color 2 - 1 my color 2 - 2] email:[my email] message:[my message] subject:[my subject]]
  </code></pre>
  <p><a href="https://i.stack.imgur.com/OpJ9F.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/OpJ9F.png" alt="enter image description here" /></a></p>
  <p>So, I thought the best way to handle it the Google Apps script is using <code>e.parameters</code> not <code>e.parameter</code>, pls correct me if this is wrong approach.</p>
  <p>In my GAS web app, only first field in both <code>color1</code> and <code>color2</code> had been posted in the related spreadsheet columns, though I expected to see array of 2 elements in each.</p>
  <p><a href="https://i.stack.imgur.com/Tl2Ko.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Tl2Ko.png" alt="enter image description here" /></a></p>
  <p>Sure, &quot;Result of the code&quot; is what I see after executed the codes in the question, &quot;Expected result&quot; is what I was expecting the code in the question will give as an output. The &quot;Targeted final result&quot; is the final result I'm working to approach, I think if I fixed the code to give the &quot;Expected result&quot;, then it should not be difficult to tune it to generate the final output as needed in the format of &quot;Targeted final result&quot;</p>
  <p>My GAS script is:</p>
  <pre><code>function doPost(e){
    output = handleResponse(e)
  }
  
  function handleResponse(e) {
    var result, message;
    // Prevent concurrent access overwriting data
    // we want a public lock, one that locks for all invocations
    var lock = LockService.getPublicLock();
    lock.waitLock(1000);  // wait 1 seconds before conceding defeat.
  
    // As we are passing JSON in the body, we need to unpairse it
    var jsonString = e.postData.getDataAsString();
    e.parameters = JSON.parse(jsonString);
    
    try {
      // next set where we write the data - you could write to multiple/alternate destinations
      var doc = SpreadsheetApp.openById(FILE_Id);
      var sheet = doc.getSheetByName(DATA_SHEET);
      
      // we'll assume header is in row 1 but you can override with header_row in GET/POST data
      var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
      var lastRow = sheet.getLastRow()
      var nextRow = lastRow + 1; // get next row
      var row = []; 
      if(lastRow &lt; 10){
        RefID = &quot;PRF.00&quot; + lastRow
      } else {
        if(lastRow &lt; 100){
          RefID = &quot;PRF.0&quot; + lastRow
        } else {
          RefID = &quot;PRF.&quot; + lastRow
        }
      }
      // loop through the header columns
      for (i in headers){
        if (headers[i] == &quot;Ref&quot;){ // special case if you include a 'Timestamp' column
          row.push(RefID);
        } else { // else use header name to get data
          if (headers[i] == &quot;Timestamp&quot;){ // special case if you include a 'Timestamp' column
           row.push(new Date());
          } else { // else use header name to get data
            row.push(e.parameters[headers[i]]);
         }
        }
      }
      // more efficient to set values as [][] array than individually
      sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
  
      // return json success results
      result = true;
      message = link;
    } catch(e){
      // if error return this
      result = false;
      message = e;
    } finally { //release lock
      lock.releaseLock();
      var output = JSON.stringify({&quot;result&quot;:result, &quot;message&quot;: message});
    }
    return output;
  }
  </code></pre>
  <p>I'm publishing my GAS a:</p>
  <p><a href="https://i.stack.imgur.com/kaOJ4.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/kaOJ4.png" alt="enter image description here" /></a></p>
  <p>If info about my client side is required, here the details:
  I'm using <code>GO</code> lang as below;</p>
  <pre class="lang-golang prettyprint-override"><code>// go build -ldflags &quot;-H=windowsgui&quot;
  package main
  
  import (
      &quot;bytes&quot;
      &quot;encoding/json&quot;
      &quot;fmt&quot;
      &quot;io/ioutil&quot;
      &quot;log&quot;
      &quot;net/http&quot;
      &quot;strings&quot;
      &quot;text/template&quot;
  
      &quot;github.com/zserge/lorca&quot;
  )
  
  // ContactDetails ...
  type ContactDetails struct {
      Email   string
      Subject string
      Message string
      Color1  []string
      Color2  []string
  }
  
  // ReturnedResult ...
  type ReturnedResult struct {
      Result  bool   `json:&quot;result&quot;`
      Message string `json:&quot;message&quot;`
  }
  
  func index(w http.ResponseWriter, r *http.Request) {
      tmpl := template.Must(template.ParseFiles(&quot;forms.html&quot;))
      if r.Method != http.MethodPost {
          tmpl.Execute(w, nil)
          return
      }
  
      r.ParseForm()
  
      details := ContactDetails{
          Email:   r.FormValue(&quot;email&quot;),
          Subject: r.FormValue(&quot;subject&quot;),
          Message: r.FormValue(&quot;message&quot;),
          Color1:  r.Form[&quot;color1&quot;], // as &quot;color1&quot; is array,
          Color2:  r.Form[&quot;color2&quot;], // as &quot;color2&quot; is array,
      }
      fmt.Printf(&quot;Post from website! r.PostFrom = %v\n&quot;, r.PostForm)
  
      sheetID := &quot;AKfycbxfMucXOzX15tfU4errRSAa9IzuTRbHzvUdRxzzeYnNA8Ynz8LJuBuaMA/exec&quot;
      url := &quot;https://script.google.com/macros/s/&quot; + sheetID + &quot;/exec&quot;
      bytesRepresentation, err := json.Marshal(details)
      if err != nil {
          log.Fatalln(err)
      }
      resp, err := http.Post(url, &quot;application/json&quot;, bytes.NewBuffer(bytesRepresentation))
      if err != nil {
          log.Fatalln(err)
      }
      // read all response body
      data, _ := ioutil.ReadAll(resp.Body)
  
      // close response body
      resp.Body.Close()
  
      webReturn := ReturnedResult{}
      if err := json.Unmarshal([]byte(data), &amp;webReturn); err != nil {
          panic(err)
      }
      fmt.Println(webReturn.Message)
  
      //tmpl.Execute(w, struct{ Success bool }{webReturn.Result})
      tmpl.Execute(w, webReturn)
  }
  
  func main() {
      // Start Host goroutine
      go func() {
          http.HandleFunc(&quot;/&quot;, index)
          http.ListenAndServe(&quot;:8090&quot;, nil)
      }()
  
      // Start UI
      ui, err := lorca.New(&quot;http://localhost:8090/index&quot;, &quot;&quot;, 480, 320)
      if err != nil {
          log.Fatal(err)
      }
      defer ui.Close()
  
      &lt;-ui.Done()
  }
  </code></pre>
  <p>With the <code>html</code> in the below template <code>forms.html</code></p>
  <pre class="lang-html prettyprint-override"><code>&lt;title&gt;Form Submittal&lt;/title&gt;
  &lt;h1&gt;Contact&lt;/h1&gt;
  &lt;form method=&quot;POST&quot;&gt;
      &lt;label&gt;Email:&lt;/label&gt;&lt;br /&gt;
      &lt;input type=&quot;text&quot; name=&quot;email&quot;&gt;&lt;br /&gt;
      &lt;label&gt;Subject:&lt;/label&gt;&lt;br /&gt;
      &lt;input type=&quot;text&quot; name=&quot;subject&quot;&gt;&lt;br /&gt;
      &lt;label&gt;Message:&lt;/label&gt;&lt;br /&gt;
      &lt;textarea name=&quot;message&quot;&gt;&lt;/textarea&gt;&lt;br /&gt;
  
      &lt;table&gt;
          &lt;tr&gt;
            &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;color1&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;color2&quot; /&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;color1&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;color2&quot; /&gt;&lt;/td&gt;
          &lt;/tr&gt;
        &lt;table&gt;
  
     &lt;input type=&quot;submit&quot;&gt;
  &lt;/form&gt;
  {{if .Result}}
      &lt;div id='foo'&gt;
          &lt;a href={{.Message}}&gt;Download PDF file&lt;/a&gt;
      &lt;/div&gt;
      &lt;h1&gt;&lt;/h1&gt;
      &lt;script&gt;
          // setTimeout(function () {document.querySelector('#foo').style.display='none'}, 5000);
      &lt;/script&gt;
  {{end}}
  </code></pre>
  <p>The console output data is:</p>
  <pre class="lang-sh prettyprint-override"><code>Post from website! r.PostFrom = map[color1:[my color 1 - 1 my color 1 - 2] color2:[my color 2 - 1 my color 2 - 2] email:[my email] message:[my message] subject:[my subject]]    
  Details = {my email my subject my message [my color 1 - 1 my color 1 - 2] [my color 2 - 1 my color 2 - 2]}
  
  bytesRepresentation = [123 34 69 109 97 105 108 34 58 34 109 121 32 101 109 97 105 108 34 44 34 83 117 98 106 101 99 116 34 58 34 109 121 32 115 117 98 106 101 99 116 34 44 34 77 101 115 115 97 103 101 34 58 34 109 121 32 109 101 115 115 97 103 101 34 44 34 67 111 108 111 114 49 34 58 91 34 109 121 32 99 111 108 111 114 32 49 32 45 32 49 34 44 34 109 121 32 99 111 108 111 114 32 49 32 45 32 50 34 93 44 34 67 111 108 111 114 50 34 58 91 34 109 121 32 99 111 108 111 114 32 50 32 45 32 49 34 44 34 109 121 32 99 111 108 111 114 32 50 32 45 32 50 34 93 125]
  </code></pre>