Iterating through array in SendGrid email template
Asked Answered
W

7

20

I'm trying to iterate through a collection and display information in a SendGrid template using Ruby on Rails.

recipient = SendGrid::Recipient.new("[email protected]")
recipient.add_substitution("username", user.github_id)
recipient.add_substitution("numbers", [1,2,3,4])

In gmail, this template arrives as:

sergiotapia
ARRAY(0x85b9d90)

The actual code for the template, copied from SendGrid's editor:

<html>
  <head>
    <title></title>
  </head>
  <body>
    <div>&lt;%body%&gt;</div>

    <div>username</div>

    <div>numbers</div>

    <p>This is a small example email.</p>
  </body>
</html>

How can I iterate through a generic array or object in a SendGrid template? For this particular example, a user has many posts and I just want to show the title of the user's posts in a <li> element.

I'm just trying things out with a simple number array to see how it SendGrid works.

Whitneywhitson answered 28/12, 2015 at 14:24 Comment(0)
N
27

Update August 2018:

Sendgrid now offers iterators from the transactional email using handlebars, here's to the docs for more info:

https://docs.sendgrid.com/for-developers/sending-email/using-handlebars#iterations

Template

<ol>
  {{#each user.orderHistory}}
   <li>You ordered: {{this.item}} on: {{this.date}}</li>
  {{/each}}
</ol>

Test data

{
  "user": {
    "orderHistory": [
      { "date": "2/1/2018", "item": "shoes" },
      { "date": "1/4/2017", "item": "hat" }
    ]
  }
}

Resulting HTML

<ol>
  <li>You ordered: shoes on: 2/1/2018</li>
  <li>You ordered: hat on: 1/42017</li>
</ol>
Newfeld answered 28/8, 2018 at 15:37 Comment(1)
docs.sendgrid.com/for-developers/sending-email/…Lexine
H
18

Iterate example for the data:

{
  "people":[{"name":"Bob"},{"name":"Sally"}]
}

Code:

{{#if people}}
  <p>People:</p>
  {{#each people}}
    <p>{{this.name}}</p>
  {{/each}}
{{/if}}

Result:

People:

Bob

Sally

Hiller answered 10/7, 2019 at 12:47 Comment(0)
E
6
{{#each data.products}}
    {{name}}: {{price}} <br/>
{{/each}}

{"data":{"products": [{"name": "Tomato", "price": "5"}, {"name": "Banana", "price": "8"}]}}
Empathic answered 10/5, 2019 at 10:9 Comment(1)
While this code may answer the question, it is better to explain how to solve the problem and provide the code as an example or reference. Code-only answers can be confusing and lack context.Differentiable
F
2

Update

SendGrid now has support for dynamic templates!

You can read about it on their blog: https://sendgrid.com/blog/how-to-use-sendgrids-dynamic-templates-for-your-transactional-emails/

Old answer:

Searching for this resulted the following GitHub issue. So it's not possible with SendGrid (yet?).

However there are other ways to do this. Using sendwithus you get access to a more powerful template editor that supports looping and iterating.

Simply set it up using your own SendGrid API key and you will be able to use the arrays in the sendwithus template which will send the mail using SendGrid.

Flemish answered 3/10, 2016 at 8:32 Comment(0)
C
1
        "businessContributors" : [
                    {
                        "total" : {
                            "amount" : 11340,
                            "title" : "Dhama Ji Total"
                        },
                        "list" : {
                            "Dhama Ji Paid" : -296310,
                            "HDFC Account" : 0,
                            "Dhama Ji Received" : 307650
                        },
                        "title" : "Dhama Ji Owner Account"
                    },
                    {
                        "total" : {
                            "amount" : -1270,
                            "title" : "Rahul Total"
                        },
                        "list" : {
                            "Rahul Paid" : 243838,
                            "Rahul Received" : 242568
                        },
                        "title" : "Rahul Account"
                    },
        ]
    
    
   in email template  :-

 
     <h4>Business Contributors </h4>
            <ul>
                {{#each businessContributors}}
                <li> {{this.title}} <br>
                    {{#each this.list}}
                     {{@key}} = {{this}} <br>
                {{/each}}  </li>
                

      
         
                <hr style="height: 2px; background-color: black;"><br>
                <h2>{{this.total.title}}</h2><br>
                <h2>{{this.total.amount}}</h2>
                <br><br>
            {{/each}}
            </ul>
Cephalad answered 11/3, 2021 at 20:24 Comment(0)
K
0

Unfortunately the templates SendGrid provides are pretty minimal at this time. The templates don't support arrays as values and there are no conditional or looping controls, so you'd need to predetermine everything prior to building the template and template content. A more robust templating system is coming soon.

Kleon answered 28/12, 2015 at 15:6 Comment(3)
youtube.com/watch?v=09s-c2JVI40 - Is it possible for me to send over a large string and replace that in the template? I can loop and render in Rails, and send that chunk to be replaced in the template. Is that kosher?Whitneywhitson
Yep, that's a good way to go, here's a similar exampleKleon
Is this answer still valid or has SenGrid implemented loops?Scraggy
K
0

Here is a workaround Sendgrid is yet to update their template engine for this

Hello guys i need to do some iteration in my sendgrid mail and ran into this issue for now i had a temporal workaround which solved the problem. here is how i worked around it

  • created a txt file and loaded my html template there
  • Note areas i wanted to iterate on i replaced with a sendgrid variable e.g %list of items%
  • read the txt file into a string create a string builder and pass all iterated object into the %list of items% variable

then send the whole string content as message through sendgrid

public void sendSimpleMessage(String message,
                String subject, 
                String toEmail,
                String fromEmail){
                 Email from = new Email(fromEmail);
                 Email to = new Email(toEmail);
                 Content content = new Content("text/html", message);
                 Mail mail = new Mail(from, subject, to, content);


                 SendGrid sg = new SendGrid(sendgridApiKey);
                 Request request = new Request();
                 try {
                      request.method = Method.POST;
                      request.endpoint = "mail/send";
                      request.body = mail.build();
                      sg.api(request);
                 } catch (IOException ex) {
                      ex.printStackTrace();
                }
        }

hope it helps someone https://github.com/sendgrid/sendgrid-nodejs/issues/221#issuecomment-361489007

Kier answered 12/3, 2018 at 11:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.