skip to Main Content

I am trying to assemble an HTML email containing Application Alerts that the user subscribed to. There are 2 Categories: "Services" and "Requests".

Each category is a Dictionary with dynamic Application names.
Each Application Name will also be a dictionary with dynamic alert types.
Those alert types will be the array that contains the alert message and timestamp.

I have tried using the lookup keyMap examples I have found online with no luck.

The End Result I am hoping will look something like this:

HTML TABLE

I have a fiddle setup with the data:
FIDDLE

JSON

{
  "Requests": {
    "Division Map Layers": {
      "Upvotes": [
        {
          "createdAt": "2023-05-08T22:12:35.500Z",
          "alert_message": "Rudy Sanchez upvoted"
        }
      ],
      "Tagged Users": [
        {
          "createdAt": "2023-05-08T22:12:44.211Z",
          "alert_message": "Rudy Sanchez tagged a user: Shawn Anderson"
        },
        {
          "createdAt": "2023-05-08T22:12:53.947Z",
          "alert_message": "Rudy Sanchez tagged a user: Jesse Brown"
        }
      ],
      "Products": [
        {
          "createdAt": "2023-05-08T22:13:05.908Z",
          "alert_message": "Rudy Sanchez added a product: Product 2"
        }
      ]
    },
    "ShutInTasks Tree": {
      "Tagged Users": [
        {
          "createdAt": "2023-05-08T22:13:25.232Z",
          "alert_message": "Rudy Sanchez tagged a user: Carol Evans-Danver"
        },
        {
          "createdAt": "2023-05-08T22:13:42.864Z",
          "alert_message": "Rudy Sanchez removed a tagged user: Carol Evans-Danver"
        }
      ]
    }
  },
  "Services": {
    "Map Services": {
      "Metadata": [
        {
          "createdAt": "2023-05-08T22:08:23.370Z",
          "alert_message": "Rudy Sanchez updated metadata"
        }
      ],
      "Messages": [
        {
          "createdAt": "2023-05-08T22:12:15.914Z",
          "alert_message": "Rudy Sanchez created a message: Testing first message"
        },
        {
          "createdAt": "2023-05-08T22:14:00.856Z",
          "alert_message": "Rudy Sanchez reacted to Rudy Sanchez's message: Testing first message"
        }
      ]
    },
    "iCompressor": {
      "CoSponsors": [
        {
          "createdAt": "2023-05-08T22:11:41.169Z",
          "alert_message": "Rudy Sanchez cosponsored"
        }
      ],
      "Timeline": [
        {
          "createdAt": "2023-05-08T22:11:51.192Z",
          "alert_message": "Rudy Sanchez created a timeline: Q1-2023"
        },
        {
          "createdAt": "2023-05-08T22:11:59.421Z",
          "alert_message": "Rudy Sanchez created a timeline: Q3-2023"
        }
      ]
    }
  }
}

I can restructure the data if it makes it easier. I have a different fiddle in which I am trying something different. It works except I can’t figure out how to put multiple Alert Categories under the same Application. I can show only a single one" "Metadata", "Messages", etc…

Different Data Structure

2

Answers


  1. <html>
      <head>
        <title>Application Alerts</title>
      </head>
      <body>
        {{#each category in data}}
          <h2>{{category}}</h2>
          {{#each application in data.[category]}}
            <h3>{{application}}</h3>
            {{#each alertType in data.[category].[application]}}
              <p>{{alertType.createdAt}} - {{alertType.alert_message}}</p>
            {{/each}}
          {{/each}}
        {{/each}}
      </body>
    </html>
    This template first iterates over the categories in your data (Services and Requests). Then, for each category, it iterates over the applications (Map Services, iCompressor, Division Map Layers, ShutInTasks Tree) and the alert types (Metadata, Messages, CoSponsors, Timeline, Upvotes, Tagged Users, Products).
    
    The data.[category] syntax is used to access the value of the category key in the data object. Similarly, data.[category].[application] is used to access the value of the application key in the data[category] object. Finally, alertType is just the name given to the current element in the data.[category].[application] array.
    
    Login or Signup to reply.
  2. It can certainly be done with the data structure you have, you would just need to make use of the @key data-variable to get the names of the categories, applications and alert types because they are all object keys in your data structure. There is no need to do any lookups because at each level we use the @key as the heading and then iterate over the object at each key. When we get to the array of alerts, we iterate over it and print the alert_message and createdAt values into our table cells.

    const template = Handlebars.compile(document.getElementById('Template').innerHTML);
    
    const data = {
      "Requests": {
        "Division Map Layers": {
          "Upvotes": [
            {
              "createdAt": "2023-05-08T22:12:35.500Z",
              "alert_message": "Rudy Sanchez upvoted"
            }
          ],
          "Tagged Users": [
            {
              "createdAt": "2023-05-08T22:12:44.211Z",
              "alert_message": "Rudy Sanchez tagged a user: Shawn Anderson"
            },
            {
              "createdAt": "2023-05-08T22:12:53.947Z",
              "alert_message": "Rudy Sanchez tagged a user: Jesse Brown"
            }
          ],
          "Products": [
            {
              "createdAt": "2023-05-08T22:13:05.908Z",
              "alert_message": "Rudy Sanchez added a product: Product 2"
            }
          ]
        },
        "ShutInTasks Tree": {
          "Tagged Users": [
            {
              "createdAt": "2023-05-08T22:13:25.232Z",
              "alert_message": "Rudy Sanchez tagged a user: Carol Evans-Danver"
            },
            {
              "createdAt": "2023-05-08T22:13:42.864Z",
              "alert_message": "Rudy Sanchez removed a tagged user: Carol Evans-Danver"
            }
          ]
        }
      },
      "Services": {
        "Map Services": {
          "Metadata": [
            {
              "createdAt": "2023-05-08T22:08:23.370Z",
              "alert_message": "Rudy Sanchez updated metadata"
            }
          ],
          "Messages": [
            {
              "createdAt": "2023-05-08T22:12:15.914Z",
              "alert_message": "Rudy Sanchez created a message: Testing first message"
            },
            {
              "createdAt": "2023-05-08T22:14:00.856Z",
              "alert_message": "Rudy Sanchez reacted to Rudy Sanchez's message: Testing first message"
            }
          ]
        },
        "iCompressor": {
          "CoSponsors": [
            {
              "createdAt": "2023-05-08T22:11:41.169Z",
              "alert_message": "Rudy Sanchez cosponsored"
            }
          ],
          "Timeline": [
            {
              "createdAt": "2023-05-08T22:11:51.192Z",
              "alert_message": "Rudy Sanchez created a timeline: Q1-2023"
            },
            {
              "createdAt": "2023-05-08T22:11:59.421Z",
              "alert_message": "Rudy Sanchez created a timeline: Q3-2023"
            }
          ]
        }
      }
    };
    
    const output = template(data);
    
    document.body.innerHTML = output;
    .mega-menu {
      border: 1px solid aquamarine;
      padding: 8px;
      font-family: sans-serif;
    }
    .main {
      font-size: 24px;
      font-weight: bold;
      color: red;
      margin-bottom: 16px;
    }
    .app-div {
      margin-left: 20px;
    }
    .app-name {
      font-size: 18px;
      font-weight: bold;
      color: blue;
      margin-bottom: 8px;
    }
    .alert-name {
      font-size: 16px;
      font-weight: bold;
      color: green;
      margin-bottom: 4px;
    }
    table {
      width: 100%;
      margin-bottom: 8px;
    }
    
    table,
    th,
    td {
      border: 1px solid lightgrey;
      border-collapse: collapse;
    }
    
    th,
    td {
      padding: 2px 4px;
    }
    
    th {
      font-size: 12px;
      text-align: left;
      color: grey;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"></script>
    <script id="Template" type="text/template">
    <div class="mega-menu">
      {{#each this}}
        <div>
          <div class="main">{{@key}}</div>
          {{#each this}}
            <div class="app-div">
              <div class="app-name">{{@key}}</div>
                {{#each this}}
                  <div class="alert-name">{{@key}}</div>
                  <div class="app-div">
                    <table>
                      <thead>
                        <tr>
                          <th style="width: 600px">Message</th>
                          <th style="width: 100px">Date</th>
                        </tr>
                      </thead>
                      <tbody>
                        {{#each this}}
                          <tr>
                            <td>{{alert_message}}</td>
                            <td>{{createdAt}}</td>
                          </tr>
                        {{/each}}
                      </tbody>
                    </table>
                  </div>
                {{/each}}
              </div>
            {{/each}}
          </div>
        {{/each}}
      </div>
    </script>

    I have created a fork of your fiddle for reference.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search