Showing posts with label AngularJS. Show all posts
Showing posts with label AngularJS. Show all posts

Sunday, April 2, 2017

Evolution of AJAX World


If you have started you carrier around 7-10 years back as web developer then probably you have experienced the evaluation practically.

Because of huge advantage of AJAX, more or less 70-80 % of modern web application has adapted this technology. The new style of AJAX implementation came in market so quickly that it’s sometime hard to remember what things were before that?

Anyway, Long ago, Netscape added a feature in browser called live script which was capable to give flavor of offline processing like form validation in client side and bit more. Slowly Live script became JavaScript with more functionality and flexibility.

The inception of DynamicHTML has started in development world, slowly XML gain its popularity in AJAX world when Microsoft added a small function in IE5 to perform XMLHttpRequest call to server.

The classic AJAX using XMLHttpRequest

This is classic style to make AJAX call using vanilla JavaScript. If you worked in very old ASP, JSP or PHP application, probably you are familiar with this style of AJAX call.

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
       // Typical action to be performed when the document is ready:
       document.getElementById("demo").innerHTML = xhttp.responseText;
    }
};
xhttp.open("GET", "yourfilename.extension", true);
xhttp.send();

Oh, did I miss something? Yes, we need to detect browser prior to AJAX call, Just to make sure we are using proper XMLHttpRequest object. Yes, XMLHttpRequest object is browser specific.

JQuery changed the whole game

Then JQuery came in market, it played major role to change face of client side app development.  It combine and packed the above code into few lines and introduce the concept of Callback.

$.ajax({url: "yoururl.com", success: function(result){
        //enjoy with result variable
    }});

And that’s all, simple, compact, no code smell and maintainable. Now, in mean time other library too started wrapping classic XMLHttpRequest request using very similar syntax.

So, as a result the concept of callback has introduced in development world. The moto of callback is, call me once you have prepared the result, or call error in mess!.

Let’s return promise rather than actual result

People started to realize that, as it is asynchronous call, it should return something by which we can take decision. Let’s give some example. The below code is based on promise and then callback function.

requestSomeData("http://example.com ") // returns a promise for the response

    .then(function(response){ // ‘then’ is used to provide a promise handler
    
    return JSON.parse(response.body); // parse the body
    
   }) // returns a promise for the parsed body

    .then(function(data){
   
    return data.something; // get the price

   }) // returns a promise for the price

    .then(function(price){ // print out the price when it is fulfilled

        //do something with the data

  });

We can consider this as fully asynchronous execution plan, even if my JSON.parse() take huge time, the execution flow will not hang the thread because I have attached then callback to ensure that someone will take care once parse completed.

Angular and Other library utilize it best

Angular 1.X introduced a way to sync all asyn call using “$q” service. This is huge power to developer to process more than one asynchronous call and print consolidated result.

Want to have more control on AJAX call? Use Observable.

RxJs introduced the concept called Observable to have more grip on AJAX call. Let’s think that we need to cancel an AJAX call in middle. Assume, the situation where need to handle multiple AJAX call. Observable is preferred than promise here.

So, an observable is like a stream and allow to pass zero or more events where the callback is called for each event. The Observable covers more including promise.
For more info, please check Observable in Angular2

    









Sunday, October 25, 2015

Pitfall in access AngularJS function from non-angular environment

In Google you will find lot of answer but there is one pitfall which I realize from my personal practical experience.

Suppose, we want to access AngularJS function from non-Angular environment (like JQuery and other JS environment). How we can do that? Very simple.

  angular.element(document.getElementById(‘Id')).scope().YourFunction();
     
Yes, we are getting element by Id and in this article here I want to focus. If you think that the “Id” is any Id value from DOM then you are wrong.

To make it work, please use the element Id where your controller is defines. Here is the example.

<div id='myId' ng-controller="IndexPageController">

In this <div> we are specifying the controller and once we want to access the function use “myId” in syntax. So the syntax will be like this.

angular.element(document.getElementById(‘myId')).scope().YourFunction();

Otherwise you may encounter function not found error. 


Sunday, October 18, 2015

Combine multiple promises and load before loading view AngularJS



It’s very common in application where we need to combine multiple promises to load and bind data in controller. 

In this article we will combine promise using “$q” service, which is well known in Angular environment.  Here is the implementation.

var app = angular.module('App', ['ngRoute']).

    config(['$routeProvider', function ($routeProvider) {
       
        $routeProvider.when('/myroute', {
               templateUrl: '../app/template.html',
               controller: 'myController',
               resolve: {
                   message: function (resultService) {
                       return resultService;
                   }
               }
           });
    }]);


    app.service('resultService', function ($http , $q) {
       
        var first = $http({ method: 'GET', url: '../Home/ReturnValue' });
        var second = $http({ method: 'GET', url: '../Home/ReturnValue' });

        return $q.all([first, second]).then(function (results) {
            return {
                first: results[0].data,
                second: results[1].data
            };
        });


    });

Please, have a look that we are combining both HTTP call using “$q” an returning result as a single object.

The object is getting return by resolve function which is defined in route. As the service is getting call in resolve of route , the data will get load before loading the view.

Here is the controller for the route.

    app.controller('myController', function ($scope, message) {
        $scope.time1 = message.first;
        $scope.time2 = message.second;

    });

Here is the output of the application.


Resolve promise before loading route in AngularJS



Sometime it’s needed to load data before loading view in application. AngularJS has option to implement same in place of routing.

We can say to AngularJS that before redirect to view, let’s complete the promise at first. Here is the implementation.

var app = angular.module('App', ['ngRoute']).
    config(['$routeProvider', function ($routeProvider) {
       
        $routeProvider.when('/myroute', {
               templateUrl: '../app/template.html',
               controller: 'myController',
               resolve: {
                           message: function (nameService) {
                               return nameService.returnName();
                           }
               }
           }).
             otherwise({
                 redirectTo: '/'
             });
    }]);

You can notice that, “myroute” routing entry has taken resolve parameter which takes service as function argument. We will define the service now. Here is the implementation of service.


    app.service('nameService', function () {
        this.returnName = function () {
            return "Sourav Kayal";
        };
    });


Here is the controller which takes “message” as argument which will return by “resolve” in routing section.


    app.controller('myController', function ($scope, message) {
        $scope.name = message;
    });


And once we run the application, we will see the name has returned to controller.