1

I have an Ember application which i'd like to include Toastr notifications in. I want to use the library to provide a cookie warning messages which I can then restyle to fit the rest of the website's theme.

However, after inclusion, I cannot get the library to work properly, the console reports a GET being performed: However, I believe that the unique way Ember works may be causing me issues? I have found another SO question which has lead me onto this train of thought.

Community
  • 1
  • 1
Ryan Soap
  • 13
  • 1
  • 4

1 Answers1

3

We use Toastr with Ember in our application, so I'll detail how we do it:

Installing Toastr

Toastr is installed through Bower, and then included into the build through the ember-cli-build.js file

// ember-cli-build.js

...

module.exports = function(defaults) {
  ...
  app.import('bower_components/toastr/toastr.js');
  ...
}

Accessing Toastr

The "Ember Way" to interface with a library like this is to wrap it in a service. We created a really simple "notifications" service that wraps the Toastr library. This is the entire thing:

// app/services/notifications.js

/* global toastr */

import Ember from 'ember';

const { Service, on } = Ember;

export default Service.extend({

  initToaster: on('init', function() {
    toastr.options = {
      debug: false,
      positionClass: 'toast-top-right',
      onclick: null,
      fadeIn: 300,
      fadeOut: 1000,
      timeOut: 5000,
      extendedTimeOut: 1000
    };
  }),

  clear() {
    toastr.clear();
  },

  success(message, title) {
    toastr.success(message, title);
  },

  info(message, title) {
    toastr.info(message, title);
  },

  warning(message, title) {
    toastr.warning(message, title);
  },

  error(message, title) {
    toastr.error(message, title);
  }

});

Using the Service

Now you can inject your service anywhere you want to use Toastr. For example, a controller could use it like this:

// some controller

import Ember from 'ember';

const { Controller, inject } = Ember;
const { service } = inject;


export default Controller.extend({

  notifications: service(),

  actions: {
    save() {
      this.get('model').save()
      .then(() => {
        this.get('notifications').success('Saved successfully!');
      })
      .catch(() => {
        this.get('notifications').error('There was an error!');
      });
    }
  }
});
Alex LaFroscia
  • 961
  • 1
  • 8
  • 24
  • Any reason you chose to require each route/controller/component that needs notifications to use `Ember.inject.service` rather than injecting the service via an initializer? – Justin Niessner Oct 26 '15 at 03:15
  • It's easier to stub out the notification service during testing when done this way, that's the main reason. I also prefer the fact that this method is explicit about what is being added to the class; it's easier to tell what's available to it than needing to remember what is being injected elsewhere. – Alex LaFroscia Oct 26 '15 at 06:08