2

How can I retrieve all data from a form's sublist? Ie, ideally retrieve all rows in the sublist as a array of objects.

/**
 * @NApiVersion 2.x
 * @NScriptType Suitelet
 * @NModuleScope SameAccount
 */

define(['N/ui/serverWidget', 
        'N/email', 
        'N/runtime', 
        'N/search',
        'N/file', 
        'N/log'],

/**
 * @param {ui} ui
 * @param {email} email
 * @param {runtime} runtime
 * @param {search} search
 * @param {file} file
 * @param {log} log
 */
function(ui, email, runtime, search, file, log) {


    function onRequest(context) {
        // On GET I create a form and add a sublist inline editor to it.

        if (context.request.method === 'POST') {
            var sublistData = context.request.parameters.sublistdata;

            // sublistData is not an array its funny string. See below:
            // 2017-5-16\u000111\u00012017-5-19\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u00011\u0001\u0001Me\u0001\u0001\u0001\u0001\u00012\u0001\u0001F\u0001\u0001\u0001INSERT\u00011\u0001F\u0001\u0001\u0001\u0001\u0001\u00022017-5-22\u000111122122\u00012017-5-12\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u00011\u0001\u0001Me\u0001\u0001\u0001\u0001\u00012\u0001\u0001F\u0001\u0001\u0001INSERT\u00011\u0001F\u0001\u0001\u0001\u0001\u0001

            //How can I get the sublist row data in a better format?
        }
    }

    return {
        onRequest: onRequest
    };

});
sazr
  • 24,984
  • 66
  • 194
  • 362

2 Answers2

4

What's happening is that NetSuite delimits sublist values in a request object by the non-printable Unicode control characters \u0001 (between fields) and \u0002 (between rows).

You can use request.getLineCount() and request.getSublistValue() to retrieve the results.

var lines = context.request.getLineCount({ group: "sublist" });
for(var i = 0; i < lines; i++) {
  var field1 = context.request.getSublistValue({ group: 'sublist', name: 'field1', line: i });
  var field2 = context.request.getSublistValue({ group: 'sublist', name: 'field2', line: i });
}
michoel
  • 3,725
  • 2
  • 16
  • 19
1

Now that SuiteScript 2.1 is in beta and supports ES6, you can populate an entire record as follows. First, use NApiVersion 2.1 in your script

 * @NApiVersion 2.1

Then make sure you require the N/record module

 define(['N/record'],  function (record) {
   // ... your code in here ...
 }

Then somewhere inside your code, define this function ...

function buildRecordData() {
  // load the record you want
  const rec = r.load({
    id: '1234',         // your record's internal id here
    type: 'salesorder'  // your record's type here
  })

  let data = {}
  const sublistIds = rec.getSublists()

  // loop through all sublists for this record type
  for (let sublistId of sublistIds) {
    // add a property to the object for each sublistId
    data[sublistId] = []

    // get the columns of the sublist
    let sublistFields = rec.getSublistFields({ sublistId })
    let count = rec.getLineCount({ sublistId })

    // loop through the lines of the sublist and build an object for each
    for(let line = 0; line < count; line++) {
      let x = {}
      for (let fieldId of sublistFields) {
        x[fieldId] = rec.getSublistValue({ sublistId, fieldId, line })
      }
      data[sublistId].push(x)
    }
  }
  return data
}    

When you call this script it will give you an object. The properties of the returned object correspond to the sublist of the record. Each sublist is an array of objects with each element of the array representing a line of the sublist.

Obviously, this could be overkill. If you only want one sublist and you know it's id, or if you only want a few fields from the line and you know their id's. But you can modify this code to return a smaller data set.