Re: communication error- email with velocity script custom object- multiple

SandyBarta99
Level 2

communication error- email with velocity script custom object- multiple

errorm.pngerror2.PNG

 

Hi all and

We are trying to come up with Velocity Script to display field data from an Custom Object when certain criteria are met. I have it working when there is just one qualifying product but when a person has 2 or more qualifying products, the script does not complete and when I preview the email it give a Communication Failure error as you can see above.

 1- User qualifies for a renewal for 1 product-mostly it will show no errors

2- User qualifies for more than 1 product - above errors will show

- can't it be because the database it needs to check it is huge?

Code

 

 

 

 

 

#foreach( $A__Installed_Product in $A__Installed_Product__cList )
#set($startDate = $convert.parseDate(${A__Installed_Product.Warranty_Start__c}, "yyyy-MM-dd"))
#set($formattedStartDate = $date.format("dd/MM/yyyy", $startDate))
#set($endDate = $convert.parseDate(${A__Installed_Product.Warranty_End__c}, "yyyy-MM-dd"))
#set($formattedEndDate = $date.format("dd/MM/yyyy", $endDate))
#set( $defaultTimeZone = $date.getTimeZone().getTimeZone("Europe/London") )
#set( $defaultLocale = $date.getLocale() )
#set( $calNow = $date.getCalendar() )
#set( $ret = $calNow.setTimeZone($defaultTimeZone) )
#set( $calConst = $field.in($calNow) )
## determine date 30 days from now
$calNow.add($calConst.DATE,30)
#set( $thirtyDaysAwayDate = $date.format("dd/MM/yyyy",$calNow) )
#if ( $formattedEndDate == "$thirtyDaysAwayDate" && ${A__Installed_Product__cList.get(0).A__Status__c}== "Installed (Auto-validated)" &&${A__Installed_Product.Product2List.get(0).Has_Orderable__c}=="1" && !${A__Installed_Product__cList.get(0).1_Contract_End_Date__c} && !${A__Installed_Product__cList.get(0).2_Contract_End_Date__c} && !${A__Installed_Product__cList.get(0).3o_Contract_End_Date__c})
Orderable PS+:              ${A__Installed_Product.Product2List.get(0).Has_Orderable__c}  <br>
30 Day Date:       $thirtyDaysAwayDate <br>
eComm:    ${A__Installed_Product.Product2List.get(0)._eCommerce_Options__c}  <br>
Product:              ${A__Installed_Product.A__Product_Name__c}  <br>
Serial No:              ${A__Installed_Product.Serial_Number__c}<br>
Warranty Start:           $formattedStartDate<br>
Warranty End:             $formattedEndDate<br>
Basic Material:              ${A__Installed_Product.Product2List.get(0).Basic_Material__c} <br>
"===========================================" <br>
#if ( ${A__Installed_Product.Product2List.get(0).eCommerce_Options__c} == "1")   
href="https://wwww=${A__Installed_Product.EC_Hashed_Purchase_Key__c}"><strong>Buy extended cover now</strong></a></p></td>
#else
href="https://wwww?q=${A__Installed_Product.Product2List.get(0).Basic_Material__c}"><strong>Where to buy</strong></a></p></td>
#end                     
#end
#end
<br>

 

 

 

 

 


When I try doing it in the recommended way, it won't show me anything

https://nation.marketo.com/t5/product-discussions/velocity-script-foreach-loop-trying-to-display-mul...


Declare list

 

 

 

#set($qualifyingproducts=[])
#set($void=$qualifyingproducts.add($A__Installed_Product ))
"++++++++++"
$qualifyingproducts
"+++++++++++

 

 

 

 

Code

 

 

 

#set($qualifyingproducts=[])
#foreach( $A__Installed_Product in $A__Installed_Product__cList )
#set($startDate = $convert.parseDate(${A__Installed_Product.Warranty_Start__c}, "yyyy-MM-dd"))
#set($formattedStartDate = $date.format("dd/MM/yyyy", $startDate))
#set($endDate = $convert.parseDate(${A__Installed_Product.Warranty_End__c}, "yyyy-MM-dd"))
#set($formattedEndDate = $date.format("dd/MM/yyyy", $endDate))
#set( $defaultTimeZone = $date.getTimeZone().getTimeZone("Europe/London") )
#set( $defaultLocale = $date.getLocale() )
#set( $calNow = $date.getCalendar() )
#set( $ret = $calNow.setTimeZone($defaultTimeZone) )
#set( $calConst = $field.in($calNow) )
## determine date 30 days from now
$calNow.add($calConst.DATE,30)
#set( $thirtyDaysAwayDate = $date.format("dd/MM/yyyy",$calNow) )
#if ( $formattedEndDate == "$thirtyDaysAwayDate" && ${A__Installed_Product__cList.get(0).A__Status__c}== "Installed (Auto-validated)" &&${A__Installed_Product.Product2List.get(0).Has_Orderable__c}=="1" && !${A__Installed_Product__cList.get(0).1_Contract_End_Date__c} && !${A__Installed_Product__cList.get(0).2Contract_End_Date__c} && !${A__Installed_Product__cList.get(0).3Contract_End_Date__c})
#set($void=$qualifyingproducts.add($A__Installed_Product ))
#foreach(A__Installed_Product in $qualifyingProducts )
Orderable PS+: ${A__Installed_Product.Product2List.get(0).Has_Orderable__c} <br>
30 Day Date: $thirtyDaysAwayDate <br>
eComm: ${A__Installed_Product.Product2List.get(0).eCommerce_Options__c} <br>
Product: ${A__Installed_Product.A__Product_Name__c} <br>
Serial No: ${A__Installed_Product.Serial_Number__c}<br>
Warranty Start: $formattedStartDate<br>
Warranty End: $formattedEndDate<br>
Basic Material: ${A__Installed_Product.Product2List.get(0).Basic_Material__c} <br>
"===========================================" <br>
#if ( ${A__Installed_Product.Product2List.get(0).PS_eCommerce_Options__c} == "1")
href="https://wwww=${A__Installed_Product.EC_Hashed_Purchase_Key__c}"><strong>Buy extended cover now</strong></a></p></td>
#else
href="https://wwww?q=${A__Installed_Product.Product2List.get(0).Basic_Material__c}"><strong>Where to buy</strong></a></p></td>
#end
#end
#end
<br>

 

 

 

12 REPLIES 12
SanfordWhiteman
Level 10 - Community Moderator

Re: communication error- email with velocity script custom object- multiple

Please remember to use the syntax highlighter ("Insert/Edit Code") to post code. I edited your post in this case.

 

Your code doesn't make a heckuva lot of sense, I must say. 🙂 It repeatedly refers to the first item in the list (get(0) means index [0]) even though it's looping over all the items. I'd say fully 100% of the time this is not what you want.


Also, you shouldn't be using formal references (${variable}) in #directives. Use $simple references instead.

 

And you shouldn't compare to quoted references like

 

#if( $formattedEndDate == "$thirtyDaysAwayDate" )

 

 

Compare more simply:

 

#if( $formattedEndDate.equals($thirtyDaysAwayDate) )

 

 

Try in fact to never use == at all. It's buggy in certain cases. Always use equals().

 

What you're sort of dismissing as "the recommended way" is specifically filtering the list. But it has to be implemented correctly. Looking at your 2 snippets, you're resetting $qualifyingproducts to an empty List; this means any items you add to $qualifyingproducts before that are removed.

 

Some of the above are just stylistic improvements, but they all increase the ability to read, reason about, and troubleshoot code.

 

Now, to the question of why you might get a timeout when there are multiple matching objects. You're not breaking out of the loop, so the entire list is being checked. But even if you were breaking when you found the first qualifying product (and if that product were early in the list) it's still extremely unlikely that the number of qualifying products would make a difference on its own.

 

Rather, I would consider how many product objects there are in the list, period. Are we talking 1000s of objects per lead? You can debug this to some degree by creating a fake list (e.g. #set( $TestList = [ { "name" : "value" }, { "name" : value" }, ... ] )) and running the same code over that list. You have direct control over the number of objects in the list in this case, although it's true that you won't be able to simulate the overhead of reading the data from the Marketo database and passing it into Velocity.

SandyBarta99
Level 2

Re: communication error- email with velocity script custom object- multiple

Many thanks @SanfordWhiteman for your detailed explanation.

I have implemented all your recommendations.

I followed your recommendations for the qualifiyinproducts list, which part is wrong?

 I still get the error 😞... 

 

 

 

 

 

 

 

 

 

#set($qualifyingproducts=[])		
		
#foreach( $A__Installed_Product in $A__Installed_Product__cList )
		
 		#set($startDate = $convert.parseDate($A__Installed_Product.Warranty_Start__c, "yyyy-MM-dd"))
        #set($formattedStartDate = $date.format("dd/MM/yyyy", $startDate))		
        #set($endDate = $convert.parseDate($A__Installed_Product.Warranty_End__c, "yyyy-MM-dd"))		
        #set($formattedEndDate = $date.format("dd/MM/yyyy", $endDate))		
   		#set( $defaultTimeZone = $date.getTimeZone().getTimeZone("Europe/London") )
		#set( $defaultLocale = $date.getLocale() )
		#set( $calNow = $date.getCalendar() )
		#set( $ret = $calNow.setTimeZone($defaultTimeZone) )
		#set( $calConst = $field.in($calNow) )
		## determine date 60 days from now 
		$calNow.add($calConst.DATE,60)
		#set( $thirtyDaysAwayDate = $date.format("dd/MM/yyyy",$calNow) )
        
##Search list
#if ( $formattedEndDate.equals($thirtyDaysAwayDate)) && $A__Installed_Product__cList.SVMXC__Status__c.equals ("Installed (Auto-validated)") &&$A__Installed_Product.Product2List.Has_Orderable__c.equals("1") && !$A__Installed_Product__cList.1e_Contract_End_Date__c && !$A__Installed_Product__cList.2Contract_End_Date__c && !$A__Installed_Product__cList.3Contract_End_Date__c)		
#set($void=$qualifyingproducts.add($A__Installed_Product ))
#end
#end


## Display results in a table, if there are multiple results display more than just one.
#foreach($A__Installed_Product in $qualifyingProducts )
	
         	 Orderable +:	${A__Installed_Product.Product2List.Has_Orderable__c}  <br>
             30 Day Date:	 $thirtyDaysAwayDate <br>	
             eComm:	${A__Installed_Product.Product2List.eCommerce_Options__c}  <br>	
             Product:	${A__Installed_Product.A__Product_Name__c}  <br>	
             Serial No:	${A__Installed_Product.Serial_Number__c}<br>	
             Warranty Start:	$formattedStartDate<br>	
             Warranty End:	$formattedEndDate<br>	
             Basic Material:	${A__Installed_Product.Product2List.Basic_Material__c} <br>	
                                 		
                                		
   "===========================================" <br>		
   #if ( $A__Installed_Product.Product2List.eCommerce_Options__c.equals("1"))    		
href="https://AAAAAAAAAAAAA?pk=$A__Installed_Product.EC_Hashed_Purchase_Key__c"><strong>Buy extended cover now</strong></a></p></td> 		
    		
                            		
#else		
		
href="https://AAAAAAAAAAAAAAA?q=$A__Installed_Product.Product2List.Basic_Material__c"><strong>Where to buy</strong></a></p></td> 		
    		
	
#end	
#end
<br>		

 

 

 

 

 

 

I tried a more simple code... without success. Now I don't get the communication error, but the rendering error. Use only qualifies for one product and still don't show....:-(... it was working with the wrong code.... weird

 

 

 

 

 

#set( $qualifyingProducts = [] )
#foreach( $A__Installed_Product in $A__Installed_Product__cList )
		#set( $void = $qualifyingProducts.add($A__Installed_Product) )



#foreach( $A__Installed_Product in $qualifyingProducts)
#set($void=$qualifyingproducts.add($A__Installed_Product ))

#end
#end
#foreach($A__Installed_Product in $qualifyingProducts )

Serial Number: $A__Installed_Product__cList.Serial_Number__c</br>
start:${A__Installed_Product__cList.Warranty_Start__c}</br>
end: ${A__Installed_Product__cList.Warranty_End__c}</br>

"==============="<p>
#end

 

 

 

 

 

 

 

SanfordWhiteman
Level 10 - Community Moderator

Re: communication error- email with velocity script custom object- multiple

Can I request that you format your code (spaces, line breaks) consistently? It's incredibly difficult to read. And when you're hunting down a syntax error, you need a consistent code style.

 

Take this snippet:

#if ( $formattedEndDate.equals($thirtyDaysAwayDate)) && $A__Installed_Product__cList.SVMXC__Status__c.equals ("Installed (Auto-validated)") &&$A__Installed_Product.Product2List.Has_Orderable_PS__c.equals("1") && !$A__Installed_Product__cList.PPL_Bespoke_Contract_End_Date__c && !$A__Installed_Product__cList.PPL_Elite_Contract_End_Date__c && !$A__Installed_Product__cList.PPL_Pro_Contract_End_Date__c)		
#set($void=$qualifyingproducts.add($A__Installed_Product ))
#end

 

Let's reformat that so it's readable, without changing the effective syntax:

#if ( $formattedEndDate.equals($thirtyDaysAwayDate)) &&
  $A__Installed_Product__cList.SVMXC__Status__c.equals("Installed (Auto-validated)") && 
  $A__Installed_Product.Product2List.Has_Orderable_PS__c.equals("1") && 
  !$A__Installed_Product__cList.PPL_Bespoke_Contract_End_Date__c && 
  !$A__Installed_Product__cList.PPL_Elite_Contract_End_Date__c && 
  !$A__Installed_Product__cList.PPL_Pro_Contract_End_Date__c )		
#set( $void = $qualifyingproducts.add($A__Installed_Product) )
#end

 

Now, it's apparent that it has a number of errors.

SanfordWhiteman_0-1620283550349.png

 

SandyBarta99
Level 2

Re: communication error- email with velocity script custom object- multiple

Thanks @SanfordWhiteman you are a star.

 

 Relationship goes as follows

 Contact>installproduct>product

 

  • Contact> install product..............  1:manyrelationship
  • install product is a junction product for the product ............1:1 relationship
  • Product >install product  ............1 to Many relationship

 Contract types  have date type field, whne I drag an drop them from left had menu they show like this

 

  • ${A__Installed_Product__cList.get(0).1_Contract_End_Date__c}
  • ${SA__Installed_Product__cList.get(0).2_Contract_End_Date__c}
  • ${A__Installed_Product__cList.get(0).3_Contract_End_Date__c}

Has orderable comes from the object- product ( 2 levels down)

  • ${A__Installed_Product__cList.get(0).Product2List.get(0).Has_Orderable__c}

 how would you advice for the code?

 

#set($qualifyingproducts=[])		
		
#foreach( A__Installed_Product in $A__Installed_Product__cList )
		
#set($startDate = $convert.parseDate($A__Installed_Product.Warranty_Start__c, "yyyy-MM-dd"))
#set($formattedStartDate = $date.format("dd/MM/yyyy", $startDate))		
#set($endDate = $convert.parseDate($A__Installed_Product.Warranty_End__c, "yyyy-MM-dd"))		
#set($formattedEndDate = $date.format("dd/MM/yyyy", $endDate))		
#set( $defaultTimeZone = $date.getTimeZone().getTimeZone("Europe/London") )
#set( $defaultLocale = $date.getLocale() )
#set( $calNow = $date.getCalendar() )
#set( $ret = $calNow.setTimeZone($defaultTimeZone) )
#set( $calConst = $field.in($calNow) )

## determine date 30 days from now 
$calNow.add($calConst.DATE,30)
#set( $thirtyDaysAwayDate = $date.format("dd/MM/yyyy",$calNow) )
        
##Search list
#if ( $formattedEndDate.equals($thirtyDaysAwayDate) 
&& $A__Installed_Product__cList.SVMXC__Status__c.equals ("Installed (Auto-validated)") 
&& $A__Installed_Product__cList.Product2List.Has_Orderable__c.equals("1")
&& !$A__Installed_Product__cList.1_Contract_End_Date__c
&& !$A_Installed_Product__cList.2_Contract_End_Date__c 
&& !$A__Installed_Product__cList.3_Contract_End_Date__c)		

#set($void=$qualifyingproducts.add($A__Installed_Product ))
#end
#end
## Display results in a table, if there are multiple results display more than just one.
#foreach($A__Installed_Product in $qualifyingProducts )
	
Orderable:${SVMXC__Installed_Product.Product2List.Has_Orderable_PS__c}  <br>
30 Day Date:$thirtyDaysAwayDate <br>	
eComm:	${A__Installed_Product.Product2List.eCommerce_Options__c}  <br>	
Product:${A__Installed_Product.SVMXC__Product_Name__c}  <br>	
Serial No:${A__Installed_Product.Serial_Number__c}<br>	
Warranty Start:	$formattedStartDate<br>	
Warranty End:	$formattedEndDate<br>	
Basic Material:	${A__Installed_Product.Product2List.Basic_Material__c} <br>	
                                 		
                                		
   "===========================================" <br>		
   #if ( $A__Installed_Product.Product2List.eCommerce_Options__c.equals("1"))    		
href="https:/wwwwwww?pk=$A_Installed_Product.EC_Hashed_Purchase_Key__c"><strong>Buy extended cover now</strong></a></p></td> 		
    		
                            		
#else		
		
href="https://wwwwwwwwww?q=$A__Installed_Product.Product2List.Basic_Material__c"><strong>Where to buy</strong></a></p></td> 		
    		
	
#end	
#end
<br>		
SandyBarta99
Level 2

Re: communication error- email with velocity script custom object- multiple

funny whne approving the email I get the below error

 

Validation Error approving Warranty Expiry Emails.test no format —  <div>An error occurred when procesing the email Body! </div> <p>Encountered "(" near</p> <div><pre >#if ( $formattedEndDate.equals($thirtyDaysAwayDate) </pre><pre >&amp;&amp; $A__Installed_Product__cList.A__Status__c.equals (&quot;Installed (Auto-validated)&quot;) </pre><pre class="x-form-item-label">&amp;&amp; ${A__Installed_Product__cList.Product2List.Has_Orderable__c(&quot;1&quot;)</pre><pre >&amp;&amp; !$A__Installed_Product__cList.1_Contract_End_Date__c </pre><pre >&amp;&amp; !$SVMXC__Installed_Product__cList.2_Contract_End_Date__c </pre></div>

SanfordWhiteman
Level 10 - Community Moderator

Re: communication error- email with velocity script custom object- multiple

A loop variable must begin with a $ sign.

#foreach( A__Installed_Product in $A__Installed_Product__cList )

 

SandyBarta99
Level 2

Re: communication error- email with velocity script custom object- multiple

thanks, yes, I must have deleted when posting it here.

SandyBarta99
Level 2

Re: communication error- email with velocity script custom object- multiple

 

So I discover where the issue, or part of what it may be in prod, though not sure how to solve it, hopefully Marketo can.

 When I untick the fields from the object <product> the email prints, I I tick them again and nothing prints and I get the communication error. I have tried with basic token + the full one ( this one only give me the lead name, as it can execute the code, but no communication error. Has anybody experience this?

 

 Relationship goes as follows

 Contact>installproduct>product

 

  • Contact> install product..............  1:manyrelationship
  • install product is a junction product for the product ............1:1 relationship
  • Product >install product  ............1 to Many relationship
SanfordWhiteman
Level 10 - Community Moderator

Re: communication error- email with velocity script custom object- multiple

That's pretty well expected actually, since when you don't export any fields into Velocity, every object is null, so there can't be any additional problems processing the objects or their relationships.