The View can subscribe to events from the Controller in a similar fashion to the Controller subscribing to Storage with code similar to this:

this.controller.subscribe('dataUpdate', this.onDataUpdate.bind(this));

Populate frontend/view.js and frontend/public/summary.html as shown below:

// ...
const domUtils = {
  clearChildren(element) {
    while (element.firstChild) {
// ...

export default class MyView extends SiftView {
constructor() {
  // You have to call the super() method to initialize the base class.
  this.controller.subscribe('dataUpdate', this.onDataUpdate.bind(this));

// for more info:
presentView(value) {
  console.log('counter: presentView: ', value);

willPresentView(value) {
  console.log('counter: willPresentView: ', value);

onDataUpdate(data) {
  console.log('counter: onDataUpdate: ', data);

  if (data.counts) {
    Object.keys(data.counts).filter(key => ['messageTotal', 'wordTotal', 'wpmTotal'].includes(key)).forEach((k) => {
    document.getElementById(k).textContent = data.counts[k];

  if (data.messages && data.messages.length > 0) {
    const messages = data.messages.slice(0, 50);
    const messageList = document.getElementById('messageList');

    document.getElementById('messagesContainer').style.display = 'unset';

    const messageItemNodes ={ subject, wordCount }) => {
    const liNode = document.createElement('li'); = 'display: flex; margin-top: 16px; margin-bottom: 16px; padding: 16px; border-bottom: 1px solid #e0e0e0; flex-direction: column;'

    const subjectNode = document.createElement('h4'); = 'text-align: left;';

    const wordCountNode = document.createElement('p');
    wordCountNode.textContent = `Email word count: ${wordCount}`;
    subjectNode.textContent = subject;


    return liNode;

    messageItemNodes.forEach(node => messageList.appendChild(node));
  } else {
    document.getElementById('messagesContainer').style.display = 'none';

// ...
<!DOCTYPE html>
<html lang="en">
    <meta charset="utf-8">
    <link rel="stylesheet" href="dist/css/style.min.css">
  <body id="home">
    <div class="column">
      <div class="side-by-side">
        <div class="stat--separator">
          <div class="count" id="messageTotal">0</div>
          <div class="subtitle">Messages</div>
        <div class="stat--separator">
          <div class="count" id="wordTotal">0</div>
          <div class="subtitle">Words</div>
        <div class="stat">
          <div class="count" id="wpmTotal">0</div>
          <div class="subtitle">Words/Message</div>
      <div class="info-steps">
        <span>A few steps to get you started:</span>
          <li>Connect your email account from the inputs menu on the left</li>
          <li>Pull down some emails with the blue button</li>
          <li>See the counters go up...</li>
          <li>Now zap this example and start your own Sift!</li>
      <div class="info-larger">
        Make me bigger!
      <div class="message-list" id="messagesContainer" style="display: none;">
        <h2>List of Emails</h2>
        <ul id="messageList">
    <!-- Your Sift view bundle -->
    <script src="dist/js/view.umd-es2015.min.js"></script>

All we are saying here is when we have some data, use the onDataUpdate() method. Data either will come when the Sift loads and the presentView() method will be called (line 20) or when an update takes place (line 16).
To complete the presentation and bubble up the data to our presentation we need to add one more line in summary.html

Try running your Sift!


If nothing happened...

Did you remember to purge your DB?