Alerts and Exceptions

Demonstration of capturing exceptions and alerting in Angular.

by Jeremy Likness

HTML

<script src="https://code.angularjs.org/1.3.9/angular.min.js"></script>
<div ng-app="alertApp">
    <div>Click on any alert to remove it</div>
    <ul ng-controller="alertCtrl as ctrl">
        <li ng-repeat="alert in ctrl.alerts" ng-click="ctrl.dismiss(alert.id)">{{alert.message}}</li>
    </ul>
    <div ng-controller="appCtrl as ctrl">
        <button ng-click="ctrl.addAlert()">Add Alert</button>
        <button ng-click="ctrl.throwError()">Throw Error</button>
    </div>
</div>

JavaScript

(function (app) {

    function service() {}

    angular.extend(service.prototype, {
        alerts: [],
        alertId: 1,
        addAlert: function (msg) {
            this.alerts.push({
                id: this.alertId,
                message: msg
            });
            this.alertId += 1;
        },
        removeAlert: function (alertId) {
            var i;
            for (i = this.alerts.length - 1; i >= 0; i -= 1) {
                if (this.alerts[i].id === alertId) {
                    this.alerts.splice(i, 1);
                    break;
                }
            }
        }
    });

    app.service("alertSvc", service);

    function alertController(alertSvc) {
        this.alertSvc = alertSvc;
    }

    angular.extend(alertController.prototype, {
        dismiss: function (alertId) {
            this.alertSvc.removeAlert(alertId);
        }
    });

    Object.defineProperty(alertController.prototype, "alerts", {
        configurable: false,
        enumerable: true,
        get: function () {
            return this.alertSvc.alerts;
        }
    });

    app.controller("alertCtrl", ["alertSvc", alertController]);

    function appController(alertSvc) {
        this.alertSvc = alertSvc;
    }

    angular.extend(appController.prototype, {
        addAlert: function () {
            this.alertSvc.addAlert("Added at " + new Date());
        },
        throwError: function () {
            throw new Error("Oops!");
        }
    });

    app.controller("appCtrl", ["alertSvc", appController]);
    
    app.config([
        "$provide", "$httpProvider", function (provide, httpProvider) {

            provide.decorator("$exceptionHandler", function($delegate, $injector) {
                return function(exception, cause) {
                    var alertSvc = $injector.get("alertSvc");
                    alertSvc.addAlert(exception.toString());
                    $delegate(exception, cause);
                };
            });
        }]);

   ...