Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's a good way to handle flash notifications in meteor (with meteor-router)?

I am using meteor along with meteor-router for client and server side routing. I'm wondering what a good way to handle site notifications, specifically "flash" type ones.

In the global layout.html I can have a handlebars output a message if a "message" session variable is set, but the message shouldn't stick around once the app is routed to a new url with Meteor.Router.to().

What's a good solution to having "flash" notifications? Or, how can I automatically clear a session variable after routing to a new URL.

layout.html:

<head>
  <title>Meteor App</title>
</head>
<body>
  {{> global-layout}}
</body>

<template name="global-layout">
   {{#if message}}
      <div class="message">{{message}}</div>
   {{/if}}
   {{renderPage}}
</template>

then in layout.js

Template['global-layout'].message = function () {
  return Session.get('message');
};
like image 771
Diogenes Avatar asked Dec 29 '12 23:12

Diogenes


1 Answers

I'm using a Meteor.Router.filter for this. This filter will be applied to all routes, therefore all flashes will be cleared on all url changes.

routes.js

Meteor.Router.filters({
  // clearSeenMessages filter clears all seen messages. 
  // This filters is applied to all pages 
  clearSeenMessages: function (page) {
    flash.clear();
    return page;
  },
});

// applies to all pages
Meteor.Router.filter('clearSeenMessages');

Here's the rest of the implementaion, aspects were borrowed from telesc.pe

client/views/flashes/flash_item.html

    <template name="flashItem">
      {{#if show}}
        <div class="alert-box {{type}}">
          {{message}}
          <a class="close"  href="">&times;</a>
        </div>
      {{/if}}
    </template>

client/views/flashes/flash_item.js

// When the template is first created
Template.flashItem.created = function () {
  // Get the ID of the messsage
  var id = this.data._id;
  Meteor.setTimeout(function () {
    // mark the flash as "seen" after 100 milliseconds
    flash.Flashes.update(id, {$set: {seen: true}});
  }, 100);
}

client/views/flashes/flashes.html

<template name="flashes">
  {{#each flashes}}
    {{> flashItem}}
  {{/each}}
</template>

client/views/flashes/flashes.js

Template.flashes.flashes = function () {
  return flash.Flashes.find();
}

client/views/app.html

<body>
  <!-- add the flashes somewhere in the body -->
  {{> flashes}}
</body>

client/lib/flashes.js

// flashes provides an api for temporary flash messages stored in a
// client only collecion
var flash = flash || {};

(function (argument) {
  // Client only collection
  flash.Flashes = new Meteor.Collection(null);

  // create given a message and optional type creates a Flash message.
  flash.create = function (message, type) {
    type = (typeof type === 'undefined') ? 'error' : type;
    // Store errors in the 'Errors' local collection
    flash.Flashes.insert({message: message, type: type, seen: false, show: true});
  };

  // error is a helper function for creating error messages
  flash.error = function (message) {
    return flash.create(message, 'error');
  };

  // success is a helper function for creating success messages
  flash.success = function (message) {
    return flash.create(message, 'success');
  };

  // info is a helper function for creating info messages
  flash.info = function (message) {
    return flash.create(message, 'info');
  };

  // clear hides viewed message
  flash.clear = function () {
    flash.Flashes.update({seen: true}, {$set: {show: false}}, {multi: true});
  };
})();

Usage

flash.success('This is a success message');
flash.error('This is a error message');
flash.info('This is a info message');
like image 178
Kyle Finley Avatar answered Nov 18 '22 14:11

Kyle Finley