Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Typescript

Using AngularJs Interceptors to Show Notifications to End Users

5.00/5 (7 votes)
27 Dec 2015CPOL2 min read 17.8K  
Describes a generic way to show notifications to end users using AngularJs's Interceptors and HTTP methods

Introduction

This article describes a generic way to show notifications to end users using AngularJs's Interceptors and HTTP methods based on users actions, e.g., if the user is posting a record, a notification like “Saving…” will be shown. If the user is deleting a record, a “Deleting…” will be shown and so on. The code is using AngularJs and Typescript.

Background

I had a requirement to show notifications to end users on every action that they perform so if there is a lag while communicating with database, etc., the users are aware that something is happening.

For example, the user is trying to see all the associated records related to a contact, a “Loading…” notification is displayed:

Image 1

One way of doing this would be to inject the notification service into all of the AngularJs services and then based on the operation, show the notification and once the promise is returned, then hide the notification. This is fine if there is only one page and couple of actions; however this will be violating the DRY principle if this needs to be repeated in many – many pages.

Therefore, a better solution is to use AngularJs’s interceptors to intercept the Request / Response and inject the Notification Service and show the notifications. AngularJs, interceptors will enable us to intercept and inject custom code before the request is performed and after the response is returned and displayed to the end user.

Please see the code example below. I will show the actual implementation of the Notification Service in a separate post.

Using the Code

The code is very self-explanatory, however the important lines are:

  • Registering the custom Http Interceptor with AngularJs:
    JavaScript
    angular.module("CRM").config(['$httpProvider', ($httpProvider: any) => {
      $httpProvider.interceptors.push(HttpInterceptor.Factory); // Inject our custom interceptor
            }]);
  • Injecting the Custom Notification Service in the Custom Interceptor:
    JavaScript
    static $inject = ['$injector', '$q'];
    constructor($injector: ng.auto.IInjectorService, $q) {
        this.$q = $q;
        this.notificationService = $injector.get("CRM.Common.NotificationService");
        this.$log = $injector.get('$log');
        this.$injector = $injector;
    }
    
  • Using the Custom Notification Service and parsing the Http Method:
    JavaScript
    public request = (config) => {
        this.notificationService.blockUi(this.getMessageBasedOnHttpMethod(config.method));
        return config;
    };
    

The full code is given below:

JavaScript
module CRM.Config {

    ((): void => {

        angular.module('CRM', [
            'toaster',
            'ngTasty',
            'ui.bootstrap',
            'darthwade.dwLoading']);

        angular.module("CRM").config(['$httpProvider', ($httpProvider: any) => {
            $httpProvider.defaults.headers.common['X-Requested-With'] = 
                      'XMLHttpRequest'; // Make angular messages MVC Ajax compatible.
            $httpProvider.interceptors.push(HttpInterceptor.Factory); // Inject our custom interceptor
        }]);

    })();

    /**
     * Custom Http Interceptor
     */
    export class HttpInterceptor {
        private $q;
        public notificationService: CRM.Common.INotificationService; // Custom Notification Service
        public $log: ng.ILogService;
        public $injector: ng.auto.IInjectorService;

        /**
         * Show the error notification and unblock the UI
         */
        public responseError = (rejection) => {
            
            this.notificationService.unblockUi();
            if (rejection.data.message) {
                this.notificationService.showError(rejection.data.message);
            }
            return this.$q.reject(rejection);
        };

        /**
         * Unblock the UI as there is no error in response
         */
        public response = (response) => {
            if (this.$q.when(response)) {
                this.notificationService.unblockUi();
                return this.$q.when(response);
            }
            return response || this.$q.when(response);
        }

        /**
         * Block the UI and show notification based on the HTTP method
         */
        public request = (config) => {
            this.notificationService.blockUi(this.getMessageBasedOnHttpMethod(config.method));
            return config;
        };

        private getMessageBasedOnHttpMethod(httpMethod : string): string {

            var message = "";

            switch (httpMethod.toLowerCase()) {
                case "get":
                    message = "Loading...";
                    break;
                case "post":
                    message = "Saving...";
                    break;
                case "put":
                    message = "Updating...";
                    break;
                case "delete":
                    message = "Deleting...";
                    break;
                default:
                    message = "Please Wait...";
            }

            return message;
        }

        /**
         * If there was any error while doing the request, unblock UI and show message
         */
        public requestError = (rejection) => {
            this.$log.log("requestError", rejection);
            this.notificationService.unblockUi();
            if (rejection.data.message) { // If MVC filter related errors
                this.notificationService.showError(rejection.data.message);
            }
            return this.$q.reject(rejection);
        };

        public static Factory($injector, $q: ng.IQService) {
            HttpInterceptor.Factory.$inject = ["$injector", "$q"];
            return new HttpInterceptor($injector, $q);
        }

        static $inject = ['$injector', '$q'];
        constructor($injector: ng.auto.IInjectorService, $q) {
            this.$q = $q;
            this.notificationService = $injector.get("CRM.Common.NotificationService");
            this.$log = $injector.get('$log');
            this.$injector = $injector;
        }
    }
}

History

  • 27th December 2015: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)