Category Archives: Angular JS

As i know jQuery, i wanted to know how i can relate the knowledge i know about scripting could help in learning AngularJs , Which helped me to know that the ideology behind both of them is completely different, though as the comparison makes the learning easy and understandable.

Starting on with JQuery, as everyone know this is client side library, that play around the DOM.As it is said, it is all about DOM manipulation.
Where you think a lot about ‘QUERYing the DOM’ for DOM elements and doing something.

For example, when you get data from the server which you intend to display in some format in the DOM, in jQuery, you need to

  • FIND’ where in the DOM you want to place this data, then
  • UPDATE/APPEND’ it there by creating a new node or just setting its innerHTML. Then when
    you want to update this view, you then
  • FIND’ the location and
  • UPDATE’.

To put in another way, in jQuery, we need to think about CSS selectors, that is, where is the div or an element that has a class or attribute, etc., so that I can get their HTML or color or value.

This cycle of find and update all done within the same context of getting and formatting data from server, is gone in AngularJS.

AngularJs :
This is a client side framework that offers to build the independent client side application. Here as the name framework says , Angular implements a MVC platform.

  • Model – your models contains your semantic data. Models are usually JSON objects. Models exist as attributes of an object called $scope. You can also store handy utility functions on $scope which your templates can then access.
  • View – Your views are written in HTML. The view is usually not semantic because your data lives in the model.
  • Controller – Your controller is a JavaScript function which hooks the view to the model. Its function is to initialise $scope. Depending on your application, you may or may not need to create a controller. You can have many controllers on a page.

If you want some changes on your UI think from model data change perspective. Change your data and UI will re-render itself. You need not to play around DOM each time unless and until it is hardly required and that should also be handled through Angular Directives.

With AngularJS, The model is the truth, and you always think from that ANGLE.
You have your model (JavaScript objects you are already used to) and the value of the model tells you about the model and about the view, and an operation on the model automatically propagates to the view, so you don’t have to think about it. You will find yourself in AngularJS no longer finding things in the DOM.
You are not bothering yourself of whether the view reflecting this value is a checked box or resides in a td element.
that is why Angular is: Architect and then design.

About the Design:
So the rule here is Don’t design and mark up rather Architect and then design.
For which Angular uses the concept called DIRECTIVES.

Directives:
Directives in Angular are extended HTML attributes with the prefix ng-.There are many default directives that Angular provides us with , like.
ng-app, ng-init, ng-model and many more which have their own purpose on the applcations from initializing the app to binding the values.
In addition to these built-in directives, directives can also be customized.
Plugins vs. Directives

Plugins extend jQuery. AngularJS Directives extend the capabilities of your browser.

In jQuery we define plugins by adding functions to the jQuery.prototype. We then hook these into the DOM by selecting elements and calling the plugin on the result. The idea is to extend the capabilities of jQuery.

For example, if you want a carousel on your page, you might define an unordered list of figures, perhaps wrapped in a nav element. You might then write some jQuery to select the list on the page and restyle it as a gallery with timeouts to do the sliding animation.

The AngularJS way is to extend the capabilities of native looking HTML. You should write HTML that looks like HTML, extended
with custom attributes and elements.
Using Angular, If you want a carousel , just use a element, then define a directive to pull in a template, and make it work.Lots of small directives vs. big plugins with configuration switches

Data Binding
This is one of the most awesome features of AngularJs, As updating the view is done by AngularJs itself , differentiating it from the way we do it with jquery while responding to the events and updating the content.
Jquery :
$('ul.menu').click(function(){
$('li.menu').show(500);
});

Where the ui could be like

But in AngularJs , we can do this like,
$http( '/menu.json' ).then( function ( response ) {
$scope.menu.push( { item: 'Item Three' } );
});

Where our view could look like

We never had to change the controller code!(or edit manually)
But more importantly, no matter where or how the menu gets updated, the view will change too. Automatically. Neat!

5. Separation of concerns

In Angular , it is keep your CONCERNS separate,which makes the code much cleaner.

  • Your view acts as the official record of what is supposed to happen
  • your model represents your data;
  • you have a service layer to perform reusable tasks;
  • you do DOM manipulation and augment your view with directives;
  • and you glue it all together with controllers.

There are many differences in the approaches we do with JQuery and AngularJs, which cannot be put in simply theoretically, concepts like
Closures in JQuery , while scope in AngularJS
Manual DOMchanges vs Data binding (with more examples)
Service Objects vs Helper Functions
Instatiation vs Dependency injection (DI)
needs more examples, which will be added as a continuation to this.

Protractor (protractortest.org) is an end-to-end test framework specifically for AngularJS apps. It was built by a team in Google and released to open source. Protractor is built on top of WebDriverJS and includes important improvements tailored for AngularJS apps. Here are some of Protractor’s key benefits:

  • You don’t need to add waits or sleeps to your test. Protractor can communicate with your AngularJS app automatically and execute the next step in your test the moment the webpage finishes pending tasks, so you don’t have to worry about waiting for your test and webpage to sync.
  • It supports Angular-specific locator strategies (e.g., binding, model, repeater) as well as native WebDriver locator strategies (e.g., ID, CSS selector, XPath). This allows you to test Angular-specific elements without any setup effort on your part.
  • It is easy to set up page objects. Protractor does not execute WebDriver commands until an action is needed (e.g., get, sendKeys, click). This way you can set up page objects so tests can manipulate page elements without touching the HTML

Follow these simple steps, and in minutes, you will have you first Protractor test running:
 
1) Set up environment
Install the command line tools ‘protractor’ and ‘webdriver-manager’ using npm:
npm install -g protractor

Start up an instance of a selenium server:
webdriver-manager update & webdriver-manager start

This downloads the necessary binary, and starts a new webdriver session listening on http://localhost:4444.

2) Write your test

// It is a good idea to use page objects to modularize your testing logic
var angularHomepage = {
    nameInput: element(by.model('yourName')),
    greeting: element(by.binding('yourName')),
    get: function() {
        browser.get('index.html');
    },
    setName: function(name) {
        this.nameInput.sendKeys(name);
    }
};

// Here we are using the Jasmine test framework
// See http://jasmine.github.io/2.0/introduction.html for more details

describe('angularjs homepage', function() {
    it('should greet the named user', function() {
        angularHomepage.get();
        angularHomepage.setName('Julie');
        expect(angularHomepage.greeting.getText()).
        toEqual('Hello Julie!');
    });
});

3) Write a Protractor configuration file to specify the environment under which you want your test to run:

exports.config = {
    seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['testFolder/*'],
    multiCapabilities: [{
        'browserName': 'chrome',
        // browser-specific tests
        specs: 'chromeTests/*'
    }, {
        'browserName': 'firefox',
        // run tests in parallel
        shardTestFiles: true
    }],
    baseUrl: 'http://www.angularjs.org',
};

4) Run the test:

Start the test with the command:

protractor conf.js

In this article, I am going to explain AngularJS with a store application example. This application’s aim is to list out the available products and details like name, price and image. The user can view more information about the product like description, specifications, and reviews in the tab panel. In this example, I am going to explain only the UI part of AngularJS, without the server side interaction.

You should download:
1. angular.min.js
2. bootstrap.min.css

Before going to start building any AngularJS application, we need to add the AngularJS java script library to our html file using the following script tag:

       <!-- index.html -->
       <!DOCTYPE html>
       <html>
       <head>
        <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
        <script type="text/javascript" src="angular.min.js"></script>
       </head>

       <body>

       </body>
      </html>
     

In this example, we’ll also use twitter bootstrap CSS for styling purpose I have added that too. Now we have our store application index file. For any angular JS application the starting point is a module.

Module
You can think of a module as a container for the different parts of your app – controllers, services, filters, directives etc. Most applications have a main method that instantiates and wires together the different parts of the application. Angular apps don’t have a main method. Instead, modules declaratively specify how an application should be bootstrapped. There are several advantages to this approach. Let’s take a look at them.

  • Where we write pieces of our Angular application.
  • Makes our code more maintainable, testable, and readable.
  • where we define dependencies for our application, which means one module depends on other modules as the following:
  • module2

It’s time to create our first module for our store application. Let’s create a file with name “app.js” and add the following line.

    //file app.js
    var app = angular.module('store', [])
  

After adding above line, please save it. In the above line, we have created a variable called app and assigned an angular module called ‘store’. The following diagram will explain above line in an app.js file.

module3

Include above module into our store application index file.

    <!-- index.html -->
    <!DOCTYPE html>
    <html>
      <head>
        <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
        <script type="text/javascript" src="angular.min.js"></script>
        <script type="text/javascript" src="app.js"></script>
       </head>
       <body>
       </body>
      </html>
  

We need to add a directive called ‘ng-app’ to our index file and assign the name of newly created module to it:

    <!-- index.html -->
    <!DOCTYPE html>
    <html ng-app="store">
      <head>
        <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
        <script type="text/javascript" src="angular.min.js"></script>
        <script type="text/javascript" src="app.js"></script>
      </head>
      <body>
      </body>
    </html>
  

‘ng-app’ directive tells to the html file to run the ‘store’ module when document loads. We have created a module called ‘store’ and included that module using ‘ng-app’ directive in our index.html file. Now I am going to explain about expressions in AngularJS.

Expressions:
AngularJS expressions are JavaScript-like code snippets that are usually placed in bindings such as {{ expression }}. Using expressions, we can insert dynamic values into our HTML as follows:

module7

For more information about Angular JS expressions, check out this URL https://docs.angularjs.org/guide/expression. Now add a string operation expression to our index.html file:

     <!-- index.html -->
     <!DOCTYPE html>
     <html ng-app="store">
       <head>
        <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
        <script type="text/javascript" src="angular.min.js"></script>
        <script type="text/javascript" src="app.js"></script>
       </head>

       <body>
         <p> {{"hello" + "you"}}
       </body>
      </html>
   

When you run the ‘index.html’ file in browser, it loads with the text “hello you”:

ag_screen1

So far, we have covered directives, modules, and expressions quite successfully.

Controllers & ng-controller directive:
In order to add some behavior to our application, we need a controller. So, let us add a simple java script object which contains a product information like name, price, and description. It’s just a simple object we want to print to the page.

        //file app.js
         var app = angular.module('store', []);
         var product = {name: 'gem', price: 2.5, description: 'My first gem'}
     

To use this product object, we need to add a controller to our application. Controllers are where we define our application’s behaviour by defining functions and values. First, we must go ahead with wrapping our javascript in a closure and add a controller called ‘StoreController’:

        //file app.js
         (function(){
           var app = angular.module('store', []);
           var product = {name: 'gem', price: 2.5, description: 'My first gem'}

           app.controller('StoreController', function(){

           });
          })();
       

Assign the product object to a controller property inside the controller:

        //file app.js
         (function(){
           var app = angular.module('store', []);
           var product = {name: 'gem', price: 2.5, description: 'My first gem'}

           app.controller('StoreController', function(){
              this.storeproduct = product;
           });
          })();
       

Now how do we print out this data in our webpage? Just add a placeholder ‘div’ inside our index.html file as follows:

       <!-- index.html -->
       <!DOCTYPE html>
       <html ng-app="store">
       <head>
        <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
        <script type="text/javascript" src="angular.min.js"></script>
        <script type="text/javascript" src="app.js"></script>
       </head>

       <body>
         <div>
           <h1> Product name </h1>
           <h2> $Product price </h2>
           <p> Product Description </p>
         </div>
       </body>
      </html>
     

In order to use the StoreController behaviour, we need to attach that inside of index.html by using ‘ng-controller’ directive. The ng-controller directive attaches a controller class to the view. This is a key aspect of how angular supports the principles behind the Model-View-Controller design pattern.

MVC components in angular:

  • Model — Models are the properties of a scope; scopes are attached to the DOM where scope properties are accessed through bindings.
  • View — The template (HTML with data bindings) that is rendered into the View.
  • Controller — The ngController directive specifies a Controller class; the class contains business logic behind the application to decorate the scope with functions and values.

Now set the controller class using ‘ng-controller’ directive:

       <!-- index.html -->
       <!DOCTYPE html>
       <html ng-app="store">
       <head>
        <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
        <script type="text/javascript" src="angular.min.js"></script>
        <script type="text/javascript" src="app.js"></script>
       </head>

       <body>
         <div ng-controller='StoreController as store'>
           <h1> Product name </h1>
           <h2> $Product price </h2>
           <p> Product Description </p>
         </div>
       </body>
      </html>
     

Here StoreController is the name of the controller. ‘as store’ means ‘as’ is a keyword in AngularJS to create alias. Which means store is alias for ‘StoreController’. Now, we can access the product data as follows using expressions:

       <!-- index.html -->
       <!DOCTYPE html>
       <html ng-app="store">
       <head>
        <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
        <script type="text/javascript" src="angular.min.js"></script>
        <script type="text/javascript" src="app.js"></script>
       </head>

       <body>
         <div ng-controller='StoreController as store'>
           <h1> {{ store.storeproduct.name}} </h1>
           <h2> ${{ store.storeproduct.price}} </h2>
           <p> {{ store.storeproduct.description}} </p>
         </div>
       </body>
      </html>
     

If you run the index file in a browser, it will display the information of the product. Notice that the scope of the controller property is within the ng-controller ‘div’. It will not accessable outside the ‘div’.

ag_screen2

Built-In Directives
So far we have covered the controller. Now let’s see how to display a button called ‘Add to cart’ which will show or hide based on a value of product property. We can achieve this using AngularJS built-in directives.

First add a button called ‘Add to cart’ within our product specific ‘div’ in ‘index.html’ and add a property called ‘canPurchase’ to our product variable in app.js:

       <!-- index.html -->
       <!DOCTYPE html>
       <html ng-app="store">
       <head>
        <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
        <script type="text/javascript" src="angular.min.js"></script>
        <script type="text/javascript" src="app.js"></script>
       </head>

       <body>
         <div ng-controller='StoreController as store'>
           <h1> {{ store.storeproduct.name}} </h1>
           <h2> ${{ store.storeproduct.price}} </h2>
           <p> {{ store.storeproduct.description}} </p>
           <button>Add to Cart</button>
         </div>
       </body>
      </html>
     
        //file app.js
         (function(){
           var app = angular.module('store', []);
           var product = {name: 'gem', price: 2.5, description: 'My first gem', canPurchase: false}

           app.controller('StoreController', function(){
              this.storeproduct = product;
           });
          })();
       

In AngularJS, we have a built-in directive called ‘ng-show’ which can display an HTML element based on a expression. Now add the ‘ng-show’ directive to the HTML button:

       <!-- index.html -->
       <!DOCTYPE html>
       <html ng-app="store">
       <head>
        <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
        <script type="text/javascript" src="angular.min.js"></script>
        <script type="text/javascript" src="app.js"></script>
       </head>

       <body>
         <div ng-controller='StoreController as store'>
           <h1> {{ store.storeproduct.name}} </h1>
           <h2> ${{ store.storeproduct.price}} </h2>
           <p> {{ store.storeproduct.description}} </p>
           <button ng-show="store.storeproduct.canPurchase">Add to Cart</button>
         </div>
       </body>
      </html>
     

If you run the index file ‘add to cart’ button will not display because the ‘canPurchase’ property of the product is false. You can test it by changing its value to true. Here the ‘ng-show’ directive tells the document to only show the button if the value of expression is true.

ag_screen3

If we want to show or hide the product based on a product property called ‘soldOut’ which means if the product property ‘soldOut’ is true, we have to hide the product on the HTML page. To do this we have another built-in directive called ‘ng-hide’ in Angular JS. Add the ‘soldOut’ property to product and add ‘ng-hide’ directive to product ‘div’ by creating a new ‘div’ and wrapping the product info:

        //file app.js
         (function(){
           var app = angular.module('store', []);
           var product = {name: 'gem', price: 2.5, description: 'My first gem', canPurchase: false, soldOut: true}

           app.controller('StoreController', function(){
              this.storeproduct = product;
           });
          })();
       
       <!-- index.html -->
       <!DOCTYPE html>
       <html ng-app="store">
       <head>
        <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
        <script type="text/javascript" src="angular.min.js"></script>
        <script type="text/javascript" src="app.js"></script>
       </head>

       <body>
         <div ng-controller='StoreController as store'>
           <div ng-hide="store.storeproduct.soldOut">
             <h1> {{ store.storeproduct.name}} </h1>
             <h2> ${{ store.storeproduct.price}} </h2>
             <p> {{ store.storeproduct.description}} </p>
          </div>
         </div>
       </body>
      </html>
     

If you run the above index file in a browser the product information will not display because the product property ‘soldOut’ is true which means the ‘ng-hide’ directive will evaluate based on product property ‘ng-hide’.

ag_screen4

Till now we have only one product information. I want to display more products. First, add more products information to our plain java script object ‘product’ in app.js file and change the name to ‘products’.

        //file app.js
         (function(){
           var app = angular.module('store', []);
           var products = [
{"name": "Azurite",
    "description": "Some gems have hidden qualities beyond their luster, beyond their shine... Azurite is one of those gems.",
    "price": 110.50
  },
  {
    "name": "Bloodstone",
    "description": "Origin of the Bloodstone is unknown, hence its low value. It has a very high shine and 12 sides, however.",
    "price": 22.90
  },
  {
    "name": "Zircon",
    "description": "Zircon is our most coveted and sought after gem. You will pay much to be the proud owner of this gorgeous and high shine gem.",
    "price": 1100
  }]

           app.controller('StoreController', function(){
              this.storeproducts = products;
           });
          })();
       

Now we have a product array. How can we display all the products in our HTML template? We can display all products using array index as follows:

  .....
  <body>
         <div ng-controller='StoreController as store'>
           <div>
             <h1> {{ store.storeproduct[0].name}} </h1>
             <h2> ${{ store.storeproduct[0].price}} </h2>
             <p> {{ store.storeproduct[0].description}} </p>
          </div>

          <div>
             <h1> {{ store.storeproduct[1].name}} </h1>
             <h2> ${{ store.storeproduct[1].price}} </h2>
             <p> {{ store.storeproduct[1].description}} </p>
          </div>

           <div>
             <h1> {{ store.storeproduct[2].name}} </h1>
             <h2> ${{ store.storeproduct[2].price}} </h2>
             <p> {{ store.storeproduct[2].description}} </p>
          </div>
         </div>
       </body>

Above example will work, but if you observe the code we are repeating the same code with an array index. It’s neither a good idea nor dynamic. In AngularJS, we have a directive called ‘ng-repeat’ to iterate product array to display all products information.

  .....
  <body>
     <div ng-controller='StoreController as store'>
       <div ng-repeat="product in store.storeproducts">
         <h1> {{ product.name}} </h1>
         <h2> ${{product.price}} </h2>
         <p> {{ product.description}} </p>
       </div>
     </div>
  </body>

Now the code looks clean. Open the index file in browser:

ag_screen5

What we have learned so far:

  • Directives: HTML annotations that trigger javascript behaviour
  • Modules: Where our application components live
  • Controllers: Where we add application behaviour
  • Expressions: How values get displayed within the page

Filters
A filter formats the value of an expression for display to the user. They can be used in view templates, controllers or services and it is easy to define your own filter. Filters can be applied to expressions in view templates using the following syntax:

{{ expression | filter }}

E.g. the markup {{ 12 | currency }} formats the number 12 as a currency using the currency filter. The resulting value is $12.00.

Let’s add twitter-bootstrap CSS to our current code:

  .....
  <body>
         <div ng-controller='StoreController as store'>
          <ul class="list-group">
          <li class="list-group-item" ng-repeat="product in store.storeproducts">
             <h3> {{ product.name}}
             <em class="pull-right"> ${{product.price}} </em>
             </h3>
          </li>
         </ul>
         </div>
       </body>

Output:
ag_screen6

Here I am displaying the ‘$’ symbol as static. To display the product price with currency symbol with decimal points we a built-in filter called “currency”. Now add the currency filter to product price.

  .....
  <body>
         <div ng-controller='StoreController as store'>
          <ul class="list-group">
          <li class="list-group-item" ng-repeat="product in store.storeproducts">
             <h3> {{ product.name}}
             <em class="pull-right"> {{product.price | currency}} </em>
             </h3>
          </li>
         </ul>
         </div>
       </body>

Output:

ag_screen7

There are many built-in filters in AngularJS. Following are the examples of those:

filters1

ng-src directive

Till now we have a product with name, price and description. Say for example we have different sizes of images for each product. Add the images array to product array:

   //file app.js
         (function(){
           var app = angular.module('store', []);
           var products = [
{name: "Azurite",
    description: "Some gems have hidden qualities beyond their luster, beyond their shine... Azurite is one of those gems.",
    price: 110.50,
    images: [
     {
      full: "image-full.jpg",
      thumb: "image-thumb.jpg"
     }
    ]
  },
  {
    name: "Bloodstone",
    description: "Origin of the Bloodstone is unknown, hence its low value. It has a very high shine and 12 sides, however.",
    price: 22.90,
    images: [
     {
      full: "image-full.jpg",
      thumb: "image-thumb.jpg"
     }
    ]
  },
  {
    name: "Zircon",
    description: "Zircon is our most coveted and sought after gem. You will pay much to be the proud owner of this gorgeous and high shine gem.",
    price: 1100,
    images: [
     {
      full: "image-full.jpg",
      thumb: "image-thumb.jpg"
     }
    ]
  }]

           app.controller('StoreController', function(){
              this.storeproducts = products;
           });
          })();

Now we have images array for each product. How do we display the image in our template for each product? We can access the image for each product within an expression as follows:

{{ product.images[0].full}}

Add an image tage in our template and provide the src attribute as follows:

img_src

Using Angular markup like {{hash}} in a src attribute doesn’t work right: The browser will fetch from the URL with the literal text {{hash}} until Angular replaces the expression inside {{hash}}. The ngSrc directive solves this problem. To display the product image we need to use ng-src directive.

img_ng_src

Now our code looks like this:

    .....
  <body>
         <div ng-controller='StoreController as store'>
          <ul class="list-group">
          <li class="list-group-item" ng-repeat="product in store.storeproducts">
             <h3> {{ product.name}}
             <em class="pull-right"> ${{product.price | currency}} </em>
             <img ng-src="{{product.images[0].full}}" />
             </h3>
          </li>
         </ul>
         </div>
       </body>
  

Output:
ag_screen8

ng-click directive

I want to add simple tabs and panels functionality to our template to show product information. To do that, I am going to use twitter bootstrap tab functionality as follows:

tabs1

Add the twitter bootstrap tabs and panels functionality to our template as follows:

    <section>
      <ul class="nav nav-pills">
        <li>
          <a href>Description</a>
        </li>
        <li>
          <a href>Specifications</a>
        </li>
        <li>
          <a href>Reviews</a>
        </li>
     </ul>

     <!--  Description Tab's Content  -->
           <div class="panel">
             <h4>Description</h4>
             <blockquote>product description</blockquote>
           </div>

          <!--  Spec Tab's Content  -->
          <div class="panel">
            <h4>Specifications</h4>
            <blockquote>product specifications</blockquote>
          </div>

         <!--  Review Tab's Content  -->
         <div class="panel">
           <h4>Reviews</h4>
           <blockquote>product reviews</blockquote>
        </div>
    </section>
   

In AngularJS we have a built-in directive called ‘ng-click’. It allows you to specify custom behavior when an element is clicked.We can assign an expression to it, that expression should evaluate upon click event.Add the tab functionality & ng-click to each tab reference:

     .....
  <body>
         <div ng-controller='StoreController as store'>
          <ul class="list-group">
          <li class="list-group-item" ng-repeat="product in store.storeproducts">
             <h3> {{ product.name}}
             <em class="pull-right"> ${{product.price | currency}} </em>
             </h3>
           <section>
            <ul class="nav nav-pills">
             <li>
              <a href ng-click="tab = 1">Description</a>
             </li>
             <li>
              <a href ng-click="tab = 2">Specifications</a>
             </li>
             <li>
              <a href ng-click="tab = 3">Reviews</a>
            </li>
           </ul>

           <!--  Description Tab's Content  -->
           <div class="panel">
             <h4>Description</h4>
             <blockquote>product description</blockquote>
           </div>

          <!--  Spec Tab's Content  -->
          <div class="panel">
            <h4>Specifications</h4>
            <blockquote>Not yet</blockquote>
          </div>

         <!--  Review Tab's Content  -->
         <div class="panel">
           <h4>Reviews</h4>
           <blockquote>Not Yet</blockquote>
        </div>

      </section>
     </li>
    </ul>
   </div>
  </body>

Output:
ag_screen9

ng-show directive
How do we make the tabs trigger panel to show? If we click on any tab the tab value will get updated. which means all expressions which contains ‘tab’ value will get updated. Expressions define 2 way data binding which means expressions are re-evaluated when a property changes.

The ‘ng-show’ directive shows or hides the given HTML element based on the expression provided to the ngShow attribute. The element is shown or hidden by removing or adding the .ng-hide CSS class onto the element. The .ng-hide CSS class is predefined in AngularJS and sets the display style to none. Let’s add ‘ng-show’ to our panels:

 .....
 <section>
   <ul class="nav nav-pills">
     <li>
       <a href ng-click="tab = 1">Description</a>
     </li>
     <li>
       <a href ng-click="tab = 2">Specifications</a>
     </li>
     <li>
       <a href ng-click="tab = 3">Reviews</a>
     </li>
   </ul>
  <!--  Description Tab's Content  -->
    <div class="panel" ng-show=" tab === 1">
      <h4>Description</h4>
      <blockquote>{{product.description}}</blockquote>
    </div>

    <!--  Spec Tab's Content  -->
     <div class="panel" ng-show=" tab === 2">
      <h4>Specifications</h4>
      <blockquote>Not yet</blockquote>
     </div>

     <!--  Review Tab's Content  -->
       <div class="panel" ng-show=" tab === 3">
         <h4>Reviews</h4>
         <blockquote>Not Yet</blockquote>
       </div>
   </section>
 ....

Output:
ag_screen10

Now when a tab is selected it will show the appropriate panel. Here we have a problem when you refresh the page, none of the tabs were selected, which means no initial tab on refresh.

ng-init directive
How do we set an initial value for a tab? In AngularJS we have a directive called ‘ng-init’ to set an initial value for a property. ‘ng-init’ allows us to evaluate an expression in the current scope. Add the ‘ng-init’ directive to ‘section’ element:

 .....
  <!--  Description Tab's Content  -->
    <div class="panel" ng-show=" tab === 1">
      <h4>Description</h4>
      <blockquote>{{product.description}}</blockquote>
    </div>

    <!--  Spec Tab's Content  -->
     <div class="panel" ng-show=" tab === 2">
      <h4>Specifications</h4>
      <blockquote>Not yet</blockquote>
     </div>

     <!--  Review Tab's Content  -->
       <div class="panel" ng-show=" tab === 3">
         <h4>Reviews</h4>
         <blockquote>Not Yet</blockquote>
       </div>
 ....

Output:

ag_screen11

ng-class directive

It’s a good idea to show which tab is active. In twitter-bootstrap we have css class for active tabs. we need to set the class to active if current tab is selected. How do we set it?

The ‘ng-class’ directive allows you to dynamically set CSS classes on an HTML element by data binding an expression that represents all classes to be added.

ng-class = “{ css class name: expression }”

Expression to evaluates if true, set class provided css class name otherwise nothing. Now add the ‘ng-class’ directive to each tabs:

 .....
  <section ng-init=" tab = 1">
   <ul class="nav nav-pills">
     <li ng-class="{active: tab === 1}">
       <a href ng-click="tab = 1">Description</a>
     </li>
     <li ng-class="{active: tab === 2}">
       <a href ng-click="tab = 2">Specifications</a>
     </li>
     <li ng-class="{active: tab === 3}">
       <a href ng-click="tab = 3">Reviews</a>
     </li>
   </ul>
  <!--  Description Tab's Content  -->
    <div class="panel" ng-show=" tab === 1">
      <h4>Description</h4>
      <blockquote>{{product.description}}</blockquote>
    </div>

    <!--  Spec Tab's Content  -->
     <div class="panel" ng-show=" tab === 2">
      <h4>Specifications</h4>
      <blockquote>Not yet</blockquote>
     </div>

     <!--  Review Tab's Content  -->
       <div class="panel" ng-show=" tab === 3">
         <h4>Reviews</h4>
         <blockquote>Not Yet</blockquote>
       </div>
 ....

Output of clicking Description tab:

ag_screen12

Output of clicking Specification tab:
ag_acreen13

Output of clicking Reviews tab:
ag_screen14

Conclusion

In this article I have covered a simple store application using AngularJs basic directives. In my next article I will explain advanced topics in AngularJS like custom directives & attributes, server side interaction etc.

References

Thank you for reading this article. Hope you enjoyed it!

What is AngularJS?

AngularJS is a structural framework for dynamic web apps. It lets you use HTML as your template language and lets you extend HTML’s syntax to express your application’s components clearly and succinctly. Angular’s data binding and dependency injection eliminate much of the code you would otherwise have to write. And it all happens within the browser, making it an ideal partner with any server technology.

First I will explain about what we can do with HTML.

HTML is a great declarative language for static documents. It does not contain much in the way of creating applications, and as a result building web applications is an exercise in what do I have to do to trick the browser into doing what I want?

The impedance mismatch between dynamic applications and static documents is often solved with:
A library – A collection of functions which are useful when writing web apps. Your code is in charge and it calls into the library when it sees fit. For example, jQuery.

Frameworks – A particular implementation of a web application, where your code fills in the details. The framework is in charge and it calls into your code when it needs something app specific. For example, durandal, ember, etc.

Angular takes another approach. It attempts to minimize the impedance mismatch between document centric HTML and what an application needs by creating new HTML constructs. Angular teaches the browser new syntax through a construct we call directives. Examples include:

  • Data binding, as in {{}}
  • DOM control structures for repeating, showing and hiding DOM fragments.
  • Support for forms and form validation.
  • Attaching new behavior to DOM elements, such as DOM event handling.
  • Grouping of HTML into reusable components.

Don’t worry about above topics in angular JS. Following is the normal flow of a static HTML page request and response cycle:

normal_html_fllow

In the above flow, the first request comes from browser and server sends the response (HTML content & assets like css, images) back to the browser. After loading response in the browser if the user clicks any link on that page again, a request goes to server and server send the response again. Now the browser loads the entire page again (HTML content & Assests). Here in this fllow we have an issue with the response time because each request will try to load the entire page repeatedly.

To solve above issue, we can use any javascript library like jQuery/AngularJs framework to make the AJAX call to update the particular DOM elements with resonse data (most probably JSON data.) The following picture will explain the flow:

ajax_request_fllow

In the above flow, the entire page will load only first-time request from the browser. If the user clicks any link on that page it will get the response data and update the specific DOM elements. So the response time was reduced compare to normal HTML flow.

Most of the web apps using the above flow. But current trend needs a web app which will responsive and more expose of their API to support desktops & mobile apps as well.

We can achieve this using AngularJS in modern API driven applications. The following diagram will explain the modern API driven web application architecture.

modren_API_application

Now it’s time to know about Angular JS.

Prerequisites:

Before going to learn AngularJS you must know about HTML, CSS & Java Script. Also, it’s good to know about automated testing, Behavior Driven Development(BDD), and Test Driven Development(TDD).

Why AngularJS?

If you’re using JavaScript to create a dynamic website, Angular is a good choice.

  • Angular helps you organize your JavaScript
  • Angular helps create responsive (as in fast) websites
  • Angular plays well with jQuery
  • Angular is easy to test

What is Angular JS?

A simple definition for Angular JS is it is a client-side Java Script framework for adding interactivity to HTML.

Now I have an HTML page and a JavaScript function as follows.

   <!-- File index.html-->
   <!DOCTYPE html>
   <html>
     <body>
      ...
     </body>
   </html>
   <!-- app.js -->
   function Store(){ alert('Wellcome, Angular!');}

How do we tell our HTML when to trigger our JavaScript using angular JS? In the above JS code, we have a simple alert message. To do this first, we need to include the AngularJS file in the HTML header section. We can do it in two different ways:

1. Download the AngularJS into your local and set the path in script tag in HTML header section as follows:

<script src="angular.min.js"></script>

2. You can directly specify the URL as follows:

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>

Now we can tell our HTML to run the JavaScript using Directive in the body tag. A Directive is a marker on an HTML tag that tells Angular to run or reference some JavaScript code.

  <!-- File index.html-->
   <!DOCTYPE html>
   <html>
     <body ng-controller="StoreController">
      ...
     </body>
   </html>

In the above file, ng-controller is a directive in the body tag. If you run the index file in the browser it will return an alert message. This is not a working example. This example will explain about Directivies.

Getting Started with Angular Js:

Let me explain a simple working example of AngularJS.

Step1: AngularJS is distributed as a JavaScript file, and can be added to a web page with a script tag as follows:

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>

Step2: AngularJS extends HTML with ng-directives.The ng-app directive defines an AngularJS application.The ng-model directive binds the value of HTML controls (input, select, textarea) to application data. The ng-bind directive binds application data to the HTML view.

Step3: AngularJS Example

          <!-- File index.html-->
          <!DOCTYPE html>
          <html>
            <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js">
            <body>
             <div ng-app="">
 	           <p>Name: <input type="text" ng-model="name"></p>
 	           <p ng-bind="name"></p>
             </div>
            </body>
          </html>
       

AngularJS starts automatically when the web page has loaded. As you have already seen, AngularJS directives are HTML attributes with a ng prefix. The ng-app directive tells AngularJS that the ‘div’ element is the “owner” of an AngularJS application.The ng-model directive binds the value of the input field to the application variable name.The ng-bind directive binds the innerHTML of the element to the application variable name.

You can run the above example in Step3 in any browser. It will display the text which you enter in the input field. Take a look at the following screens:

The first screen is the output of above example:

plain_ajs_screen

If you enter any text in the input field it will show the same text below the input field as follows:

ajs_screen2

Advantages of Angular JS:

Angular is built around the belief that declarative code is better than imperative when it comes to building UIs and wiring software components together while the imperative code is excellent for expressing business logic.

It is a very good idea to decouple DOM manipulation from app logic. This dramatically improves the testability of the code.

  1. It is a really, really good idea to regard app testing as equal in importance to app writing. Testing difficulty is dramatically affected by the way the code is structured.
  2. It is an excellent idea to decouple the client side of an app from the server side. This allows development work to progress in parallel and allows for reuse of both sides.
  3. It is very helpful indeed if the framework guides developers through the entire journey of building an app: From designing the UI, through writing the business logic, to testing.
  4. It is always good to make common tasks trivial and difficult tasks possible.

That means Angular frees you from the following pains:

  • Registering callbacks
  • Manipulating HTML DOM programmatically
  • Marshaling data to and from the UI
  • Writing tons of initialization code just to get started

Conclusion:
Angular simplifies application development by presenting a higher level of abstraction to the developer. Like any abstraction, it comes at a cost of flexibility.

In other words, not every app is a good fit for Angular. Angular was built with the CRUD application in mind. Luckily CRUD applications represent the majority of web applications. To understand what Angular is good at, though, it helps to understand when an app is not a good fit for Angular.

Games and GUI editors are examples of applications with intensive and tricky DOM manipulation. These kinds of apps are different from CRUD apps, and, as a result, are probably not a good fit for Angular.

In these cases, it may be better to use a library with a lower level of abstraction, such as jQuery.

In this article I have covered what is Angular JS with a simple example and it’s pros & cons. Hope it was useful!

I will explain advanced concepts of AngularJS with a product store web application example in my next article.