Search code examples
netsuitefreemarkersuitescript2.0

NetSuite Advanced PDF - Unable to loop through JSON built from addCustomDataSource N/render function


Hope you can help.

I have a custom advanced PDF template on NetSuite, which needs to loop through a JSON object, constructed using the "addCustomDataSource" function from the N/render module. Right now, it only returns the FIRST line of the JSON, rather than printing every line.

Here is a snippet of what the JSON looks like after its compiled:

{
   lines: [
      {
         item: "BOM 89",
         custcol_itemdisplayname: "White Cabinet (made to order)",
         unit: "Ea",
         quantity: "1",
         amount: ".00"
      },
      {
         item: "ABC 20019 N",
         custcol_itemdisplayname: "231-670cm Natural",
         unit: "Ea",
         quantity: "1",
         amount: ".00"
      },
      {
         item: "ABC 10040 N",
         custcol_itemdisplayname: "203cm Natural",
         unit: "Ea",
         quantity: "1",
         amount: ".00"
      },
      {
         item: "ABC 10020 N",
         custcol_itemdisplayname: "115cm Natural",
         unit: "Ea",
         quantity: "1",
         amount: ".00"
      }
   ]
}

Here is a snippet of the loop I am using within the <#list> directive of the PDF template:

<#assign line_no = 0>
  <table border="0" cellpadding="1" cellspacing="1" style="width:100%;"><!-- start items -->
   <#list results.lines as result>
    <#if result_index==0>
      <tr>
        <td style="height: 29px; width: 120px;"><strong>Part Number</strong></td>
        <td style="height: 29px; width: 60px;"><strong>&nbsp;</strong></td>
        <td align="left" style="height: 29px; width: 200px; text-align: right;"><strong>Description</strong></td>
        <td align="center" style="height: 40px; width: 40px; text-align: center;"><strong>Cty of Mfg</strong></td>
        <td align="center" style="height: 29px; text-align: left; width: 60px;"><strong>UOM</strong></td>
        <td align="right" style="height: 29px; text-align: right;"><strong>Qty</strong></td>
        <td align="right" style="height: 29px; text-align: right;"><strong>Value</strong></td>
      </tr>
    </#if>
      <tr>
        <td style="width: 120px;">${result[line_no].item}</td>
        <td style="width: 60px;"><strong>&nbsp;</strong></td>
        <td align="left" style="width: 200px; text-align: right;">${result[line_no].custcol_itemdisplayname}</td>
        <td align="center" style="width: 40px; text-align: center;">UK</td>
        <td align="center" style="text-align: right; width: 60px;">Pieces</td>
        <td align="right" style="text-align: right;">${result[line_no].quantity}</td>
        <td align="right" style="text-align: right;">${result[line_no].amount}</td>
      </tr>
      <#assign line_no = line_no + 1> <-----THIS IS USED TO INCREMENT TO NEXT POSITION
  </#list>
</table>

Here is the SuiteScript snippet to create the data source as a JSON object:

       renderer.addCustomDataSource({
                format: render.DataSource.OBJECT,
                alias: "results",
                data: searchData
            });

I have used "results" as the variable in the <#list> directive as named in the SuiteScript function call above. Because the first line is returned, I am fairly positive the issue is not related to this.

As far as I see, everything is built correctly because I am also able to access specific positions of the construct within the PDF. For instance, the PDF outputs data for the following just fine:

${result[1].amount}
${result[2].amount}
${result[3].amount}

This leads me to believe the issue relates to the line_no variable in the PDF. That being said, this is the final output of the PDF itself:

enter image description here

Notice that the "line_no" variable prints each line successfully. So why would ${result[line_no].amount} NOT work? Can anyone advise what could be stopping the template from iterating through the object?

Hope to hear back soon!


Solution

  • When you <#list results.lines as result>, each result is a single line - you do not need to create your own index (line_no) to iterate. Therefore ${result[line_no].amount} should just be ${result.amount}. I'm more puzzled why it's working for the first line - but I expect it's because at that point line_no is undefined so Freemarker just ignores it.