Monday, January 19, 2015

AngularJS : On click redirect to another page

You may also like to see:

Beside the fact AngularJs is Single Page Application, but we use routes for bookmarks and for better user experience. Any application move around different UI views on for different actions or features to perform. Since AngularJs is SPA it do not reload complete page on each route change but it loads only the html for current page and inject into our current page.

In AngularJs application if you want to redirect application to another page of application, and if your navigation element is an anchor tag then you can simply assign new route's URL to href attribute of the tag.

Dashboard

But if your element to navigate is not anchor tag then you need to write a scope function which redirect to your required page and you invoke this function on your element click.

  • Drafts

  • and define that function in controller as:

    $scope.redirectToDraftPage= function () {
       $location.path('/draft');
    };
    

    As you can see it is really annoying to write a scope function for each navigator items. So best way to achieve redirection in AngularJs on element click is to write a directive for this.

    Directives


    Directives are the custom tags and attributes, way to extend HTML functionality. You can teach HTML new features using tags. AngularJs have many directives like ng-show, ng-app, ng-repeat, ng-class, ng-hide and many more.

    For more details on directive see this article.

    Directives are HTML tags and attributes. These are the way to use AngularJS extended HTML functionality. Using directives you can teach HTML new features by writing your own custom directives. AngularJS comes with a bunch of built-in directives like ng-app, ng-hide,ng-show, ng-repeat, ng-class and many others.

    Include a directive to your application, with restrict: 'A' defining that this directive is actually a extending Attribute, so whenever a element have this custom directive as attribute my defined functionality will be executed accordingly.

    So what this directive will do? It will assign a click event to that particular element which has this attribute. And it will redirect to the provided route onclick of the element.

    (function(){
    
        'use strict';
    
        function ngRedirectTo($window) {
            return {
                restrict: 'A',
                link: function(scope, element, attributes) {
                    element.bind('click', function (event) {
                        //assign ng-Redirect-To attribute value to location
                        $window.location.href = attributes.ngRedirectTo;
                    });
                }
            };
        }
        angular.module('app').directive('ngRedirectTo', ngRedirectTo);
        //inject $window service for redirection
        redirectTo.$inject = ['$window'];
    }());
    
    

    As naming convention for directive work as eace camel-case word separated by hyphen( ie, - ). so our directive ngRedirectTo will be use in html as ng-Redirect-To. Here is html:

     Dashboard 
    

    So now you include this directive to your index page and you can reuse this in your whole application wherever you want to navigate. Just add this attribute to element and assign route to it.

    If you have any feedback or suggestions or you want to add something to this article please post in comments.

    You may also like to see:

    Saturday, January 3, 2015

    Interceptor in AngularJs : Global Session & Overlay (Preloader) handling

    You may also like to see:

    Every AngularJs application communicates with remote server by making http calls and get the data in form of JSON or XML from remote server and than this data will be show to users with html.

    If your application need to interact with the remote HTTP server then AngularJs has $http service for you. It allows to communicate with backend remote web APIs using JSON or XMLHttpRequest.


    Here is the general get call using $http service:

    // Simple GET request example
    $http.get('/api/url').
    success(function(data, status, headers, config) {
    // asynchronous callback event will be trigger
    // when the call to URL is successful.
    }).
    error(function(data, status, headers, config) {
    // asynchronous callback event will be trigger
    // when en error occurred calling URL or server returns
    // response with error status.
    });
    
    post call using $http service:
    // Simple POST request example
    $http.post('/api/url', {data:'hello! Its post call data!'}).
    success(function(data, status, headers, config) {
    // asynchronous callback event will be trigger
    // when the call to URL is successful.
    }).
    error(function(data, status, headers, config) {
    // asynchronous callback event will be trigger
    // when en error occurred calling URL or server returns
    // response with error status.
    });
    

    There are many scenarios when you need to capture and make some changes to each request for example you want to insert session token to each web request for the authorization similarly you may need to capture each response to perform some actions on data like global error handling for API calls Interceptors are created for these scenarios.

    Interceptors


    $httpProvider contains an array of registered interceptors. Interceptor is an AngularJs factory, you can register it by pushing to httpProvider interceptor array in your application configurations.

    There are four different interceptors you can handle, and these four functions should be in your interceptor factory if you need to perform custom operations in it:
    1. Request Interceptor:

      A request interceptor will be invoke on each request initialization, you can change request data here like adding authorization token.
    2. Response Interceptor:

      A response interceptor will be invoke on each response from remote server, you can manipulate response here like checking pushing some data to response perform some operations on response values.
    3. Request Error Interceptor:

      A request error interceptor will be invoke if there is some error while requesting remote server, like missing header or internet disconnection. Here you can validate request and resend the request to remote server.
    4. Response Error Interceptor:

      A response error interceptor will be invoke if there is error on backend remote calls like some unhandled exception on server. Here you can handle the request by showing proper message to user or resend the request to same url or alternate if available.

    Here is the example of Interceptor factory with all above interceptor functions:

    // Interceptor example for angularJs.
    angular.module('app').factory('customInterceptor', ['$q', function($q) {  
    
    var myInterceptor = {
    request : request,
    requestError : requestError,
    response : response,
    responseError : responseError
    };
    
    // On request success
    request: function (config) {
       // Contains the data about the request before it is sent.
       console.log(config);
    
      // Return the config or wrap it in a promise if blank.
      return config || $q.when(config);
    };
    
    // On request failure
    requestError: function (rejection) {
      // Contains the data about the error on the request.
      console.log(rejection);
    
    // Return the promise rejection.
    return $q.reject(rejection);
    };
    
    // On response success
    response: function (response) {
      // Contains the data from the response.
      console.log(response); 
    
    // Return the response or promise.
    return response || $q.when(response);
    };
    
    // On response failture
    responseError: function (rejection) {
      // Contains the data about the error.
      console.log(rejection);
    
    // Return the promise rejection.
    return $q.reject(rejection);
    };
    
    return myInterceptor;
    }]);
    
    and then register it to $httpProvider interceptor array.
    angular.module('app').config(['$httpProvider', function($httpProvider) {  
       $httpProvider.interceptors.push('customInterceptor');
    }]);
    

    Examples


    Authentication Token Injector


    If you are using token based authentication for web APIs in which on authentication call server return you a token & this token is required for all the further calls so server. So now you need to provide this authentication token to all the request so here we can use the interceptor. For this we need request interceptor and need to insert token to request.

    angular.module('app').factory('authTokenInjector', ['authenticationService', function(AuthenticationService) {  
        var authTokenInjector = {
            request: function(config) {
                if (!AuthenticationService.isAnonymus) {
                    config.headers['x-session-token'] = AuthenticationService.securityToken;
                }
                return config;
            }
        };
        return authTokenInjector;
    }]);
    


    Now register it to interceptors by pushing it to $httpProvider interceptor array. After this each call will be intercepted and authToken get injected to header. It is global handling for authentication now no need to handle it for individual call.

    Overlay/Pre-loader to show


    You want to show overlay on your page unless all the calls gets completed. For this instead of handling it manually you can write it in interceptors and let this work for your complete application.

    To achieve this you can write html on your main index page for loader:

    
    
    and html:


    Now write the interceptor factory, which will show the loader when call get started and hide when all the calls get executed.But As you know there are multiple calls on a page so we will use a counter which will be incremented on each request and loader will be hide when request counter is zero:
    // Interceptor example for angularJs.
    angular.module('app').factory('overlay', ['$q', function($q) {  
    
      //initialize counter
      var requestCounter=0;
    
      var myInterceptor = {  
         request : request,
         requestError : requestError,
         response : response,
         responseError : responseError
      };
    
       // On request success
       request: function (config) {
    
        //will be incremented on each request
        requestCounter++;
    
        //show loader if not visible already
        if(!$('#preloader').is(':visible')){
            $('#preloader').show();
        }
    
        // Return the config or wrap it in a promise if blank.
        //it is required to return else call will not work
        return config || $q.when(config);
      };
    
      // On request failure
      requestError: function (rejection) {
    
         //decrement counter as request is failed
         requestCounter--;
         hideLoaderIfNoCall();   
    
         // Return the promise rejection.
         return $q.reject(rejection);
      };
    
      // On response success
      response: function (response) {
          
         //decrement counter as request is failed
         requestCounter--;
         hideLoaderIfNoCall();
    
         // Return the response or promise.
         return response || $q.when(response);
      };
    
      // On response failture
      responseError: function (rejection) {
      
    
         //decrement counter as request is failed
         requestCounter--;
         hideLoaderIfNoCall();
    
         // Return the promise rejection.
         return $q.reject(rejection);
      };
       
      function hideLoaderIfNoCall(){
         // check if counter is zero means 
         // no request is in process
     
         // use triple equals see why http://goo.gl/2K4oTX
         if(requestCounter === 0)  
            $('#preloader').hide();        
         }
    
      return myInterceptor;
    }]);
    

    Summary


    In this article we have seen what interceptors are,  try to explain different kinds of interceptor functions and what their usages are. We also implemented session injector example in which we intercepted request and injected auth token to each request. We also implemented example to globally handling the overlay on page while requests are in process.

    Please write your feedback and suggestions in comments.

    You may also like to see:
    Life insurance policy, bank loans, software, microsoft, facebook,mortgage,policy,