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:
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:
angular.module("CRM").config(['$httpProvider', ($httpProvider: any) => {
$httpProvider.interceptors.push(HttpInterceptor.Factory);
}]);
- Injecting the Custom Notification Service in the Custom Interceptor:
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:
public request = (config) => {
this.notificationService.blockUi(this.getMessageBasedOnHttpMethod(config.method));
return config;
};
The full code is given below:
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';
$httpProvider.interceptors.push(HttpInterceptor.Factory);
}]);
})();
export class HttpInterceptor {
private $q;
public notificationService: CRM.Common.INotificationService;
public $log: ng.ILogService;
public $injector: ng.auto.IInjectorService;
public responseError = (rejection) => {
this.notificationService.unblockUi();
if (rejection.data.message) {
this.notificationService.showError(rejection.data.message);
}
return this.$q.reject(rejection);
};
public response = (response) => {
if (this.$q.when(response)) {
this.notificationService.unblockUi();
return this.$q.when(response);
}
return response || this.$q.when(response);
}
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;
}
public requestError = (rejection) => {
this.$log.log("requestError", rejection);
this.notificationService.unblockUi();
if (rejection.data.message) {
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