The reason AngularJS will success: Part 2

As promised, this is the second round of this series :). I will discuss today, the four George’s tests listed bellow:

  • Load elements onto a page
  • User clicks on stuff
  • Use AJAX calls to…
  • Manipulate DOM elements

I will discuss his examples one by one following the order in his post:

Ajax calls

The author include the below 2 examples:

jQuery

$.ajax({
  url: '/ajax.php',
  dataType: 'JSON',
  success: function (data) {
    $('#element').html(data);
  },
  fail: function (data) {
    alert("AJAX failed!");
  }
});

AngularJS

$scope.myData = {};
$scope.myData.doClick = function (item, event) {
  var responsePromise = $http.get("/ajax.php");
  responsePromise.success(function(data, status, headers, config) {
    $scope.myData.fromServer = data.title;
  });
  responsePromise.error(function(data, status, headers, config) {
    alert("AJAX failed!");
  });
}

The author consider that jQuery have less code. But, he didn’t mention that the Angular code do more than a simple ajax call. In fact, it has this features:

  • Ajax call
  • Click event trigger
  • Two-way data binding
  • Looser-coupling with the DOM, because we don’t manipulate the DOM directly

Try to implement all this features with jQuery and you will see how AngularJS care for your time and the quality of your code. Furthermore, $http service supports JSONP and managing HTTP headers explicitly and in a fashion way.

DOM Manipulation

For this section, the author used the below example:

var myApp = angular.module('myApp', []);

myApp.directive('myWidget', function() {
  var linkFn;
  linkFn = function(scope, element, attrs) {
    var animateDown, animateRight, pageOne, pageTwo;
    pageOne = angular.element(element.children()[0]);
    pageTwo = angular.element(element.children()[1]);

    animateDown = function() {
      $(this).animate({
        top: '+=50'
      });
    };

    animateRight = function() {
      $(this).animate({
        left: '+=50'
      });
    };

    $(pageOne).on('click', animateDown);
    $(pageTwo).on('click', animateRight);
  };
  return {
    restrict: 'E',
    link: linkFn
  };
});

Firstable, I should notice here that he does not attack this part properly, because Angular directives are a sophisticated solution in which the purpose is extending the HTML by designing reusable component. Personally, I would appreciate that he starts by introducing Angular templating and built-in directives such as ngClick, ngHide, etc.

Secondly, the author hated the fact that we use jQuery in the above example . It’s clear now that he didn’t make any effort to understand why MVC frameworks, like AngularJS, have seen the light: Angular developers don’t want to replace jQuery but they want to provide a set of utilities to facilitate the creation of maintainable front-end applications. Indeed, they use jQuery or jqLite to manipulate the DOM.

jqLite is a tiny, API-compatible subset of jQuery that allows Angular to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most commonly needed functionality with the goal of having a very small footprint.

Scalability

This is the most interesting section, in which we can see the quality of applications that the author write. I don’t want to discuss this because maybe he have some reasons that I can’t imagine. But personally, I do anything to avoid write such a code. Yet, We can use this use case to highlight the power of AngularJS.

The author should separate the logic from the view. So, the back-end should send real data:

{
  products: [
    productA : {
      productId: 345,
      name: "product A",
      price: 120;
      imageURL: "/public/uploads/products/productA.png",
      description: "this is the description of product A",
      colors: ['red', 'blue'],
      sizes: [34, 36, 40]
    }
  ]
}

We will define a Product service to wrap product list endpoint. For this use case, Angular provide an ngRessource module that make it easy to consume REST APIs.

var productServices = angular.module('productServices', ['ngResource']);

productServices.factory('Product', ['$resource',
  function($resource){
    return $resource('products/:productId.json', {}, {
      query: {method:'GET', params:{productId:'products'}, isArray:true}
    });
  }]);

The controller should look like this:

myApp.controller('ProductList', ['$scope', 'Product', function($scope, Product) {
  $scope.products = Product.query();
}]);

and at the view level, we will have something like that:

<ul>
  <li ng-repeat="p in products">
    <img src="{{ p.imageURL }}"/>
    <span>{{ p.name }}</span>
    <b>Price: </b>{{ p.price }}
    <p>{{ p.description }}</p>
  </li>
</ul>

As you can see, the Angular solution is easier to understand, more elegant, more structured and less code (10/48 lines only !).

Finally, I notice that if you don’t want to send the whole data for any reason, you should send a patch for the modified data. Then you merge it with the existing one at the client level (on your Angular $service). Here comes the magic of AngularJS which supports two-way data binding.

Advertisements