Skip to content

Instantly share code, notes, and snippets.

@honkskillet
Last active February 21, 2017 16:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save honkskillet/74338981b36931647650 to your computer and use it in GitHub Desktop.
Save honkskillet/74338981b36931647650 to your computer and use it in GitHub Desktop.

Here is my implimentation of an angular alert service (actually factory). It is composed of a factory definition and a directive.

alert.directive.js The directive.

angular.module('myApp')
  .directive('customAlerts', function (Alert) { //injects the Alert serivce
    return {
      scope: {
        alertType: '@?',
      },
      templateUrl: 'path/to/alert.html',
      restrict: 'EA',
      link: function (scope, element, attrs) {
        scope.alertSrvs=Alert;
      }
    };
  });

alert.html The directive's HTML template

`
<div ng-repeat="alert in alertSrvs.getAlerts()" >
  <div ng-show="!alertType || alertType===alert.type" class="alert " ng-class="alert.alertClass" role="alert">
    <strong>{{alert.title}}</strong> {{alert.message}}
    <button  type="button" class="close"  ng-click="alertSrvs.removeAlert(alert);">
      <span >&times;</span>
    </button>
  </div>
</div>
`

alert.factory.js The alert factory. Stores the alerts and exposes a simple API to access them.

angular.module('myApp')
  .factory('Alert', function ($rootScope) {
    var alerts=[];
    $rootScope.$on("$locationChangeStart",function(event, next, current){ 
      alerts=[];  //Clears all alerts when route is changed
    });
    // Public API here
    return {
      getAlerts: function(){
        return alerts;
      },
      addAlert: function(alertData) {
        alerts.push(alertData);
      },
      removeAlert: function(alert){
        var index = alerts.indexOf(alert);
        alerts.splice(index,1)
      },
      clearAllAlerts: function() {
        alerts=[];
      },
    };
  });

USAGE

In your html you would use the custom element defined in your directive.

`
<!-- Show alerts of type errorAlert -->
<custom-alerts alert-type="errorAlert"></custom-alerts>
<!-- if you don't set alert-type, all alerts will be shown -->
`

In your javascript controller you inject and use the Alert factory.

angular.module('myApp')
  .controller('myCtrl', function ($scope,Alert) {  //inject the Alert factory and any other services you need
  //Do whatever your contoller does
  if(thereIsAnError){
    Alert.addAlert({
          title: 'Error',
          message: 'There has been an error',
          type: 'errorAlert', // this has to match the alert-type attribute
          alertClass: 'alert-danger', //the alert element will have this class, good for css styling
        });
  }
});

Note, this has been setup to work with twitter bootstrap styling. Please make a suggestions for improvement.

@kartech11
Copy link

I have a main page where in I would like to show the alerts. I also have modal dialog page (popup) that comes up on top of the main page.
I would like to reuse the directive and show alerts on the respective pages. There is no $locationChangeStart event that gets triggered in this case. Please can you advise how your code can help accomplish the above?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment