I am creating a Velocity Script for an email and would like to only show the script to users who have the custom objects in the script available. I am new to scripting but is there an if/then statement that can be used to say "if this custom object doesn't exist for a user, do not show the script"? Thank you!
Solved! Go to Solution.
Well, you have a bunch of items I mentioned in my previous comment to think through before you finalize your custom object structure and the velocity script. But, checking for null values along with isEmpty() function should solve your initial query of why you're seeing additional rows in your email even though you don't have any data for those product fields (e.g., product, quantity4, etc.)
#if(cartAbandonment_cList.get(0).prod1 && !cartAbandonment_cList.get(0).prod1.isEmpty())
##Display something
#end
The above is just sample script to show how'd set your if condition so you take care of both null and empty "" values. Also, ideally, you should sort your CO list in the desired order before accessing the objects/loop through the list to pick the correct CO record based on a field. In general, accessing any random custom object record w/o sorting the custom object list isn't a good idea.
I think we should steer OP away from ever using .get(0) because its meaning isn’t understood by inexperienced devs.
Always iterate over the list, just stop after certain number of items.
i.e.
#set( $list = [1,56,12,34] )
#set( $sortedList = $sorter.sort( $list ) )
#set( $itemsToDisplay = 2 )
#foreach( $item in $sortedList.subList(0, $itemsToDisplay) )
$item
#end
You can use the size() function to determine if there are CO records or not for an associated person. The script would go something like below -
#if($test_CBC_cList.size()>0) //Replace "test_CBC_c" with the API name of your CO
Non-Zero CO records
#else
Zero CO records
#end
Hope this helps.
I like to use isEmpty():
#if( !$myList.isEmpty() )
## the list exists and has > 0 items
#end
List.isEmpty() is overloaded and is the same as checking the size.
If the list dos not exist at all, size() will throw a fatal error; in the same situation, isEmpty() will fail silently, though it’s impossible to say which option is universally better. You can explicitly check the existence of the list first:
#if( $myList && !$myList.isEmpty() )
## the list exists and has > 0 items
#end
Thank you both for your input. This is the particular use case I'm trying to solve for
#if ($contributionHistory_cList.isEmpty())
Dont show anything
#else
Last Contribution Date: ${contributionHistory_cList.get(0).date}
Last Contribution Amount: ${contributionHistory_cList.get(0).contribution}
Manulife ID: ${contributionHistory_cList.get(0).manulifeID}
Plan Name: ${contributionHistory_cList.get(0).planName}
#end
If the Contribution List is Empty, it shouldn't display anything, but im still seeing the script conditions appear when previewing the email.
That's what Sandy mentioned in his comment above. In case the list does not exist at all isEmpty() will fail silently. To avoid that, you could check the existence of the list first. Also, since you're not sorting the list, FYR the 0th index would return the CO record that was last created, as records by default are sorted by create date in descending order.
Try the below script instead -
#if($contributionHistory_cList && !$contributionHistory_cList.isEmpty())
Last Contribution Date: ${contributionHistory_cList.get(0).date}
Last Contribution Amount: ${contributionHistory_cList.get(0).contribution}
Manulife ID: ${contributionHistory_cList.get(0).manulifeID}
Plan Name: ${contributionHistory_cList.get(0).planName}
#end
Hope this is helpful! Let us know how it goes.
Hi All ,
I am unfamiliar with velocity script, but I attempted to write the following script. Its purpose is to hide a table row if the product field value is empty, and the row should only be visible if the same field contains any value. Here I have created 6 tokens for 6 products. If a customer has purchased two products, only two product rows should be visible in the emailer, while the rest of the rows should not appear. Likewise, if the customer has purchased three products, three rows should be visible. However, the current implementation of the script is displaying all the rows.
Please point out where I may have gone wrong.
Script :
Well, do you have a different custom object record for each product? And, how do you determine whether the custom object record is the one you should consider in case the person record already has custom object records from the previous cart abandonments? One idea is to sort the custom object list based on the created date in descending order (even though by default the COs are sorted based on ascending order of the created date, but just in case, it's always good to sort it before you reference them), and reference the records with the same date for populating data in the email. Lastly, you don't want to hide rows (as you have mentioned in your comment), you should create and show rows for the records you want to display in the email.
Hi @Darshil_Shah1 ,
At present, the client is not sharing real-time data with us, necessitating a manual data processing approach. We will manually import the data into a custom object, there is only single custom object containing all the columns. If the customer has purchased multiple products, such as three, there will be separate columns for each product (Prod1, Prod2, Prod3), as well as separate columns for the corresponding amounts and quantities. There will be only single record present for 1 customer. The client will provide us with this data on a weekly basis, and our communication will be based on that.
Could you assist me in understanding how to sort the custom object before referencing it ?
What script-level modifications needs to be done to display rows based on the products associated with each customer ?
Thanks in advance.
Gotcha, for such use cases the integration directly creates CO records in Marketo via API, as most businesses like to send the cart abandonment email within a few hours. Anyways, you can use the below piece of script to sort the CO records in the descending order of their createdAt datetime field. Once the list is sorted, you can reference it (using the sorted list variable, and not the CO List) in your script to show the data in the email.
#set( $sortedList = $sorter.sort($customObjList,"createdAt:desc") )
The most recently updated is ${sortedList[0]}
Additionally, you say you'll have separate fields for storing each product, I find that difficult to scale. Do you have an enforced upper limit on the number of products a person could add or something like you'd display max n products of all in the abandoned cart email? If not, the number of fields on the CO could easily be a bottleneck. I'd rather advise you to coalesce data into a JSON format and write it to a text field on CO (create an additional JSON text field if you feel the text area field's limit of 30k characters might not be enough).
Lastly, if you're sending emails via a trigger-based campaign using Added to <custom object name> trigger, then you can also use the $TriggerObject to reference the CO that triggered the campaign to add data in the email. Also, could you let us know the output of $cartAbandonment_cList for one of the person records where you don't have all the products filled in? Feel free to mask any sensitive info. It'd be nice if we could see your full code as well. Thanks!
At present, there is no definitive upper limit set for the number of products, it is still under discussion from the client's side. For testing purposes, I have assumed a limit of 6 products.
I am providing you with the sample data I have created, including the fields expected from the client.
Field Description -
DataLoad : The date on which data is loaded in file and shared with us.
Quantity : No. of products in cart
CartVintage : No. of days a customer adds items to the cart until the completion of the purchase
CartId : Its unique id per cartitem
Prod1-Prod6 : Name of products
Quant1-Quant6 : Quantity of associated product
Amt1 - Amt6 : Amount of Associated product
Thanks in advance.
Yeah- agreed with Sandy here. We need to see the actual data, i.e., the actual output of cartAbandonment_cList when you preview the email for a person record. Additionally, I think you should first fix your custom object definition and then start with the velocity logic, as the logic would change per you structure your CO. E.g., you can have seperate fields for each product and it's properties (amount, quantity, name, etc.), or you could also have a single text area field with all the product details coalesced in the JSON format - your script would be different in both the case.
Hi @Darshil_Shah1 @SanfordWhiteman ,
Apologies for delayed response.
The following is dummy data from a custom object. It contains 4 records with dummy information. The actual data will be expected in the same format.
I hope I hv provided you the data in requested format.
[{prod4=null, prod2=B, amnt3=null, quant4=null, prod3=null, dateLoad=2023-06-27 00:00:00, email=xyz@abc.com, cartCreated=2023-12-04 20:35:00, quant3=null, amnt2=5000, name=Neelam, quant2=400, cartUpdated=2023-06-17 00:00:00, amnt1=200, updatedAt=2023-06-27 09:15:51, prod1=A, noOfProducts=2, quant1=200, amnt4=null, createdAt=2023-06-27 09:15:51, customerID=Dummy123}]
[{prod4=null, prod2=B, amnt3=8975, quant4=Y, prod3=X, dateLoad=2023-06-27 00:00:00, email=abc@xyz.com, cartCreated=2023-03-27 00:00:00, quant3=47, amnt2=5000, name=Saurabh T, quant2=671, cartUpdated=2023-06-17 00:00:00, amnt1=200, updatedAt=2023-06-27 09:15:51, prod1=A, noOfProducts=4, quant1=1234, amnt4=7890, createdAt=2023-06-27 09:15:51, customerID=Dummy125}]
[{prod4=null, prod2=null, amnt3=null, quant4=null, prod3=null, dateLoad=2023-06-27 00:00:00, email=xyzabc@abc.com, cartCreated=2023-05-04 13:34:00, quant3=null, amnt2=null, name=Tirth, quant2=null, cartUpdated=2023-05-04 13:34:00, amnt1=7890, updatedAt=2023-06-27 09:15:51, prod1=u, noOfProducts=1, quant1=34, amnt4=null, createdAt=2023-06-27 09:15:51, customerID=Dummy130}]
[{prod4=null, prod2=Z, amnt3=null, quant4=null, prod3=null, dateLoad=2023-06-27 00:00:00, email=abc@xyza.com, cartCreated=2023-05-04 13:34:00, quant3=null, amnt2=7890, name=Himanshi, quant2=657, cartUpdated=2023-05-04 13:34:00, amnt1=8975, updatedAt=2023-06-27 09:15:51, prod1=Y, noOfProducts=2, quant1=789, amnt4=null, createdAt=2023-06-27 09:15:51, customerID=Dummy127}]
Thanks and Regards,
Hi @Darshil_Shah1 @SanfordWhiteman ,
Hope you got chance to see my last comment.
Thanks
Hi @neelambakre, yes, we did see and responded back here.
Hi @Darshil_Shah1 , @SanfordWhiteman ,
I tested the suggested code with the sort function, and it worked as expected.
Thank you so much for the help.
Cool! You're very welcome. Please make sure you define the proper CO schema and add sorting logic in your velocity script as per your requirement to ensure your personalization is spot on!
Noted this point
Thanks again 😊
Again, a screenshot of a sheet is not useful. If you are supplying data, make it actual copy-and-pastable text.
But the contents of your CSV aren’t sufficient in any case. Please supply the output of the entire ${list} variable from Velocity. This is the only way we can see the Velocity names of the properties. The sheet will not show that.
Please start by providing actual code, not a screenshot. A screenshot is not useful for troubleshooting.
When pasting code, highlight it as Java (closest we have to Velocity syntax) using the Insert/Edit Code Sample button:
Well, you have a bunch of items I mentioned in my previous comment to think through before you finalize your custom object structure and the velocity script. But, checking for null values along with isEmpty() function should solve your initial query of why you're seeing additional rows in your email even though you don't have any data for those product fields (e.g., product, quantity4, etc.)
#if(cartAbandonment_cList.get(0).prod1 && !cartAbandonment_cList.get(0).prod1.isEmpty())
##Display something
#end
The above is just sample script to show how'd set your if condition so you take care of both null and empty "" values. Also, ideally, you should sort your CO list in the desired order before accessing the objects/loop through the list to pick the correct CO record based on a field. In general, accessing any random custom object record w/o sorting the custom object list isn't a good idea.