Monday, January 19, 2015

AngularJS : On click redirect to another page

You may also like to see:

Besides the fact, AngularJs is Single Page Application, but we use URL routes for bookmarks and for better user experience. An application navigates around the different UI views for different features and actions. Since AngularJs is doesA it do not reload the complete page on each route change but it loads only the HTML for the current page and inject into our current page.

In AngularJs application if you want to redirect the application to another page of the 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 redirects 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, it is a way to extend HTML functionality. You can teach HTML new features using directive 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 an extending Attribute, so whenever an element has 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 each camel-case word separated by hyphen( ie, - ). so our directive ngRedirectTo will be use in html as ng-Redirect-To. Here is the 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 the element and assign the 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:

    Sunday, November 30, 2014

    AngularJS : Dynamically Set Page Title

    You may also like to see:


    With AngularJS you create Single Page Application (SPA) which means you have only one page of your application and dynamically you change the content of that page. So it means that there is only one time rendering of your main Html after that you can switch or append the views without re-rendering.

    As you have one page for your complete application, but you need the different page title property for each of your page. For example : home, about us, contact us, services etc. So you need a mechanism so your page title automatically get updated when you route to any page.

    Lets see how can we achieve this with angularJs.

    First thing you need to make sure for the implementation is that your ng-app="AppName" directive should be on html tag as title tag is in head section and to make it in application scope so you can update it within angularJS application you need to make it accessible from application.

    <html ng-app="app">
       <head>
         Website Name
    ...
    


    Now title tag is expecting title property in scope and since we need this common property in all of the controllers also title tag to be in that controller scope but instead of adding this property to all controllers we move this to rootScope and as rootScope is accessible from all over the application (under the ng-app="" scope) that's why we added ng-app directive to html tag.

    Here in this code I am using Ui.Router which I found best and easiest for nested views and routing implementations.

    Here we set the title property to all the routing object so now each route know the page's title property they are redirecting to.

    //here we need to inject ui.router as we using it for routing
    var myDemoApp = angular.module('myDemoApp', ['ui.router']);
    
    //$stateprovider is the service procided by ui.router
    myDemoApp.config(['$stateProvider', function ($stateProvider) {
    
    //create route object
        
        var home= {
            url: '/home',
            templateUrl: 'views/Home.html',
            controller: 'HomeCtrl',
            title: 'home'
        },
        aboutUs= {
            url: '/aboutus',
            templateUrl: 'views/AboutUs.html',
            controller: 'AboutUsCtrl',
            title: 'About Us'
        },
        contactUs= {
            url: '/contactus',
            templateUrl: 'views/ContactUs.html',
            controller: 'ContactUsCtrl',
            title: 'Contact Us'
        };
    
    //Now add these route state privider
    
        $stateProvider
           .state('home', home)
           .state('aboutus', aboutUs)
           .state('contactUs', contactUs);
    }]);
    


    Now each rout has attached the title property with, we need to access this property and set it in $rootScope so our title tag can have access on it.

    Now we going to set this property form route configuration object to $rootScope service within each controller and for this we need to have access on state object in controller. Here we will use $state service of ui.router that will make state object available in controller.


    angular.module('myApp')
        .controller('myController', ['$rootScope', '$state', function ($rootScope, $state) {
    
            //set property to rootscope
            $rootScope.title = $state.current.title;
    
    }]);
    

    Similarly each controller will set this property to $state.current.title or custom text which will be render in title tag.

    Another easy way to achieve this is to assign it to rootScope on module run. This one time binding will set it to title property in rootScope and each route will update this accordingly.

    Here is the code to set it on module run:

    angular.module("myApp").run(function ($rootScope, $state, $stateParams) {
        
         //set it here
         $rootScope.title = $state.current.title;
        
    });
    

    So this is the easy way to set your title property dynamically. If you have any question or feedback regarding this post please post in comments.

    You may also like to see:

    Friday, October 24, 2014

    Checkbox checked Property

    You may also like to see:


    If you are working on web application have checkbox input on your page then you might need to check whether the checkbox is currently checked or not for applying some condition. There are many ways to check that is checkbox is checked or not.

    Lets firstly see the pure JavaScript ways to check the property. In JavaScript after selecting the particular element you can easily check with checked property.

    Lets see a demo, there is checkbox in your page with some unique Id i.e, myCheckBox  in following case.

    <input type="checkbox" id="myCheckBox"/>
    
    Now in JavaScript you firstly select the element and then get its checked property.
    document.getElementById('myCheckBox').checked;
    
    firstly we selected element by Id then we checked the property it will return true in case if check box is checked.

    See here demo.

    If you are working with jQuery and don't want to use pure JavaScript for this check then you have multiple ways to check this property:

    using is(':checked')


    You can use the function is() of jQuery to perform this action, what this function do is its check the selected element or set of elements for a condition you passed as argument and returns true if condition satisfied else false.

    So to use is() firstly we need to select element than check for :checked selector which works for checkboxes, radio-buttons, and select elements.
    $('#myCheckBox').is(':checked');
    

    Here is demo

    using prop()


    Prior to jQuery 1.6  function attr() was used to get the property and attributes both according to element but it was confusing so after jQuery 1.6 new functio prop() was introduced to check the current property value of element.

    Here firstly we need to know the difference between properties and attributes, Attributes are values we set in Html like we set the input textbox value to some initial text so you have set the attribute value but once page is loaded in browser and you changed the text of textbox. Here the difference will be visible on this moment attribute will still be the same you have provided in html while property will be updated with the updated value of textbox.

    Here is textbox with attribute set with default text:
    <input type="text" id="myTextBox" value='set attribute value' /> 
    
    Now in jQuery try this:
    console.log('Attribute Value is : '+$('#myTextBox').attr('value'));
    console.log('Property Value is : '+$('#myTextBox').prop('value'));
    

    Here is demo.

    So lets say you have set checked attribute in html so on first time loading your checkbox get checked by default. So now attr() will always return the `checked` for $('#myCheckBox').attr('checked')  as it was provided in html(or updated later but not the current state). So you need to check it with prop() which will provide always the updated value.

    Here is example using prop()
    $('#myCheckBox').prop('checked');
    
    Here is Demo which also show the fixed value provided by attr() if we set it in html.

    using filter :checked

    Another way to check the property is to use filter :checked in selector and then check for the length of elements. It is not recommended way and give you wrong output in case if you are working with class instead of id and there are more than one input radio button, checkbox or select elements on same page.
    var isChecked = $('#myCheckBox:checked').length > 0;
    
    Here is demo

    So we have seen multiple ways of checking the checked property of checkbox. This is the thing which web developers usually have to use and cause of confusion in some scenario to select the correct way to use it.

    Please give your feedback and suggestions for the articles in comments.

    You may also like to see:

    Thursday, September 11, 2014

    JavaScript and Date Object

    Here is Previous Part of this series:

    Today I came to know an interesting case of Date object in JavaScript, I decided to share with my readers. DateTime object is always problematic for developers, specially in Web project where you need to handle different time zones.

    JavaScript has the core class of Date, which has many useful date function. As JavaScript is client-side language and it runs on clients browser so it creates the Date object of clients local time-zone, so you don't need to handle localization for client but when you get this value on server than you need to change it to UTC (or as per business requirements). You can easily create current date-time object using:
    var dateTimeNow = new Date();
    
    or you can pass the date fields to constructor:
    var dateTime = new Date(year, month, day, hours, minutes, seconds, milliseconds); 
    
    Date class has many useful and handy function which allow you to manipulate Date object and perform different operations. You can get day, month, year, hour from date object or you can convert it to UTC date object. Similarly you can change day, month, year or time of an object.
    var dt = new Date();
    dt.setFullYear(2014); 
    dt.setMonth(9);       
    dt.setDate(11);   
    
    One important thing in JavaScript Date object every developer should know is its month start from zero so:
    dt.setMonth(0);   //set January
    dt.setMonth(1);   //set February
    dt.setMonth(2);   //set march
    dt.setMonth(3);   //set April
    dt.setMonth(4);   //set May
    dt.setMonth(5);   //set June
    

    So What will happen if you set 12 to this date object?

    If you are thinking it will give you an error then you are wrong because it won't. What actually JavaScript date object will do is it will consider January of next year on setting the 12. So it sometime may cause error or unexpected result which might confuse developer if they are unaware of behavior.
    var dt = new Date();
    dt.setFullYear(2014);
    dt.setMonth(12);
    dt.setDate(1);
    
    alert(dt.toString()) //alert January 2015
    
    Here is Demo

    The inconsistent and confusing behavior I found for which I am writing this article is, setting Date to a date object.
    If you set last date to a JavaScript date object in such a way that that date i.e, 31st for April, June, September, November or 30th ,31st for February. It will change the month.



    For instance today is 20th of April 2014, and you coded to set 31st of October in way that you set the date first before changing month, Now if you are expecting Date object of 31st October than JavaScript is not your friend here as it will change the date object to October 1st 2014.

    See code:
    var dt = new Date(2014,3,20);  // 20th April 2014
    dt.setDate(31);       //will change to 1st of May
    dt.setMonth(9);       //1st October 2014
    
    alert(dt.toString()) //alert 1st October 2014
    
    Here is Demo

    See it can be problematic and can cause a major defects if you ignored it. So always remember the following point in JavaScript Date object:
    1. If you are setting day of month than make sure to change month first than day.
    2. Remember month in JavaScript range from 0 to 11 (Jan - Dec)
    3. Be alert that JavaScript don't give error on setting month or date out from normal range.
    Life insurance policy, bank loans, software, microsoft, facebook,mortgage,policy,