When trying to send a sample email that has a velocity token, I get the following error:
An error occurred when procesing the email Rendered_Email_Velocity_Error_Area_?! Error invoking method 'get(java.lang.Integer)' in java.util.ArrayList near |
The velocity token is attempting to create a Velocity variable from the value of a lead field:
#if( $lead.apptConfirmation.isEmpty() )
#set( $lead.apptConfirmation = '[]' )
#end
#set($myDetails = '#set( $myDetails = ' + $lead.apptConfirmation + ')' )
#evaluate( $myDetails )
${myDetails[0].LastName} <br/>
${myDetails[1].LastName} <br/>
If I changes line 05 to reference a static string instead of a lead field everything works:
#set($myDetails = '#set( $myDetails = ' + '[{"LastName": "Last1"},{"LastName": "Last2"}]' + ')' )
Any ideas why the top is not working?
It seems Marketo does not want me to reference a field within a #set directive.
I am essentially following the ideas laid out by Sanford Whiteman's blog on using JSON in Velocity but am getting this unexpected error so I assume others have gotten this to work.
Message was edited by: Digital Pi (changed 2nd 'email' to 'error' in first sentence
Peter Liske (peter@digitalpi.com)
Solved! Go to Solution.
So, in sum, you need to build in a guard against the $lead.apptConfirmation being empty (which you did correctly by initializing it to "[]") but you also need to degrade gracefully if it's an empty array.
One way to do that is by using an Array iterator like $display.list, which simply outputs nothing if the array is empty:
#if( $lead.apptConfirmation.isEmpty() )
#set( $lead.apptConfirmation = "[]" )
#end
#set($myDetails = '#set( $myDetails = ' + $lead.apptConfirmation + ')' )
#evaluate($myDetails)
$display.list($myDetails,"<BR>","<BR>","LastName")
P.S....
am getting this unexpected error so I assume others have gotten this to work.
... I'm probably the only person in the world even trying this stuff, so wouldn't be so sure.
Update: I slightly changed the velocity token, removing the first two lines:
#set($myDetails = '#set( $myDetails = ' + $lead.apptConfirmation + ')' )
#evaluate($myDetails)
${myDetails[0].LastName} <br/>
${myDetails[1].LastName} <br/>
Now when I try and approve the token I get a different, but equally unhelpful error:
Validation Error approving Appt Reminder Test.velocity —
An error occurred when procesing the email Body!
Encountered ")" near
<div id="body" class="mktoText" style="font-family: Helvetica, Arial, Sans-Serif; padding:10px;">
<p>#set($myDetails = '#set( $myDetails = ' + $lead.apptConfirmation + ')' )
#evaluate($myDetails)
${myDetails[0].LastName} <br/>
${myDetails[1].LastName} <br/></p>
In this second case, you're executing this dynamically assembled VTL when approving:
#set( $myDetails = )
That's a syntax error which I think you can see.
An error occurred when procesing the email Rendered_Email_Velocity_Error_Area_?! Error invoking method 'get(java.lang.Integer)' in java.util.ArrayList near |
This is going to happen if you reference the 0th (let alone the 1st) member of an empty array.
You have to assume $lead.apptConfirmation will be empty when the email is approved, because it is not approved in the context of a lead.
Hence you're initializing $myDetails with an empty array and get the array dereferencing error.
So, in sum, you need to build in a guard against the $lead.apptConfirmation being empty (which you did correctly by initializing it to "[]") but you also need to degrade gracefully if it's an empty array.
One way to do that is by using an Array iterator like $display.list, which simply outputs nothing if the array is empty:
#if( $lead.apptConfirmation.isEmpty() )
#set( $lead.apptConfirmation = "[]" )
#end
#set($myDetails = '#set( $myDetails = ' + $lead.apptConfirmation + ')' )
#evaluate($myDetails)
$display.list($myDetails,"<BR>","<BR>","LastName")
P.S....
am getting this unexpected error so I assume others have gotten this to work.
... I'm probably the only person in the world even trying this stuff, so wouldn't be so sure.
Thanks Sanford,
With your help, I got it working, and am able to pull the JSON data out of the lead field and into a Velocity array.
In reality, It is not likely that the Velocity script would every hard code the index of an array that is formed from dynamic data the way my test was...more likely that I would use it in a loop. But, as you point out it is best to write code to prevent an invalid index and null reference.
Thanks! This approach simplifies a lot of things we were trying to do with Marketo custom objects.