UI Notifications with angular js

All we need is an easy explanation of the problem, so here it is.

I have to implement some standard notification UI with angular js. My approach is the following (simplified):

<div ng-controller="MainCtrl">
  <div>{{message}}</div>
  <div ng-controller="PageCtrl">
     <div ng-click="showMessage()"></div>
  </div>
</div>

And with the page controller being:

module.controller("PageCtrl", function($scope){
  counter = 1
  $scope.showMessage = function(){
    $scope.$parent.message = "new message #" + counter++;
  };
});

This works fine. But I really don’t like the fact that I need to call $scope.$parent.

Because if I am in another nested controller, I will have $scope.$parent.$parent, and this becomes quickly a nightmare to understand.

Is there another way to create this kind of global UI notification with angular?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Use events to send messages from one component to another. That way the components don’t need to be related at all.

Send an event from one component:

app.controller('DivCtrl', function($scope, $rootScope) {
  $scope.doSend = function(){
    $rootScope.$broadcast('divButton:clicked', 'hello world via event');
  }
});

and create a listener anywhere you like, e.g. in another component:

app.controller('MainCtrl', function($scope, $rootScope) {
  $scope.$on('divButton:clicked', function(event, message){
    alert(message);
  })
});

I’ve created a working example for you at http://plnkr.co/edit/ywnwWXQtkKOCYNeMf0FJ?p=preview

You can also check the AngularJS docs about scopes to read more about the actual syntax.

This provides you with a clean and fast solution in just a few lines of code.

Regards,
Jurgen

Method 2

You should check this:
An AngularJS component for easily creating notifications. Can also use HTML5 notifications.
https://github.com/phxdatasec/angular-notifications

Method 3

After looking at this: What's the correct way to communicate between controllers in AngularJS? and then that: https://gist.github.com/floatingmonkey/3384419

I decided to use pubsub, here is my implementation:

Coffeescript:

module.factory "PubSub", ->
  cache = {}
  subscribe = (topic, callback) ->
    cache[topic] = [] unless cache[topic]
    cache[topic].push callback
    [ topic, callback ]
  unsubscribe = (topic, callback) ->
    if cache[topic]
      callbackCount = cache[topic].length
      while callbackCount--
        if cache[topic][callbackCount] is callback
          cache[topic].splice callbackCount, 1
    null
  publish = (topic) ->
    event = cache[topic]
    if event and event.length>0
      callbackCount = event.length
      while callbackCount--
        if event[callbackCount]
          res = event[callbackCount].apply {}, Array.prototype.slice.call(arguments, 1)
      # some pubsub enhancement: we can get notified when everything
      # has been published by registering to topic+"_done"
      publish topic+"_done"
      res

  subscribe: subscribe
  unsubscribe: unsubscribe
  publish: publish

Javascript:

module.factory("PubSub", function() {
  var cache, publish, subscribe, unsubscribe;
  cache = {};
  subscribe = function(topic, callback) {
    if (!cache[topic]) {
      cache[topic] = [];
    }
    cache[topic].push(callback);
    return [topic, callback];
  };
  unsubscribe = function(topic, callback) {
    var callbackCount;
    if (cache[topic]) {
      callbackCount = cache[topic].length;
      while (callbackCount--) {
        if (cache[topic][callbackCount] === callback) {
          cache[topic].splice(callbackCount, 1);
        }
      }
    }
    return null;
  };
  publish = function(topic) {
    var callbackCount, event, res;
    event = cache[topic];
    if (event && event.length > 0) {
      callbackCount = event.length;
      while (callbackCount--) {
        if (event[callbackCount]) {
          res = event[callbackCount].apply({}, Array.prototype.slice.call(arguments, 1));
        }
      }
      publish(topic + "_done");
      return res;
    }
  };
  return {
    subscribe: subscribe,
    unsubscribe: unsubscribe,
    publish: publish
  };
});

Method 4

My suggestion is don’t create a one on your own. Use existing models like toastr or something like below.
http://beletsky.net/ng-notifications-bar/

Method 5

As suggested above, try to use external notifications library. There’re a big variety of them:

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply