Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Friday, April 11, 2014

How to use Javascript localStorage to retain values of HTML input elements on Page Refresh?

How to use Javascript localStorage to retain values of HTML input elements on Page Refresh?

localStorage in Javascript is used to retain the values of the HTML input elements on the page refresh. setItem() and getItem() methods are used to set and get the data from the localStorage. clear() method is used to clear the data from the localStorage.

Suppose I have following 2 textboxes and buttons in my HTML page. 

<input type="text" id="text1" value="" />
<button type="button" id="myButton1" onclick="myButtonClicked('text1')">Click Me</button>

<input type="text" id="text2" value="" />
<button type="button" id="myButton2" onclick="myButtonClicked('text2')">Click Me</button>

I fill some data in each textbox. Now when I refresh the page, the data is lost. I want to retain that data on the page refresh. I will use localStorage for this purpose. 

//Store values on button click
function myButtonClicked(id)
{
var aLocalStorage = [];
if(localStorage.getItem('myLocalStorage') != null)
{
aLocalStorage = JSON.parse(localStorage.getItem('myLocalStorage'));
//get stored item from localStorage by json parsing
}
    aLocalStorage.push(id);
    aLocalStorage.push(document.getElementById(id).value);
    localStorage.setItem('myLocalStorage', JSON.stringify(aLocalStorage));
    //stored the entered element id and value in localStorage by doing stringify
}

Now when the page is refresh, call the following function on $(Idocument).ready event like this

$(document).ready(function()
{
retainValues();
});

function retainValues()
{
if(localStorage.getItem('myLocalStorage') != null)
{
var aLocalStorage =[];
aLocalStorage = JSON.parse(localStorage.getItem('myLocalStorage'));

var i = 0;
while (i < aLocalStorage.length)
{   
if (document.getElementById(aLocalStorage[i]) != null)
{
document.getElementById(aLocalStorage[i]).value = shoppingCartList[i+1];
}
i = i + 2;
}
}
}

How to call both Javascript function with PHP file on the click on HTML link?

How to call both Javascript function with PHP file on the click on HTML link?

Recently, I was trying to implement logout functionality while working with PHP website. I had put logout logic in logout.php file and I was calling that file on the click of logout link like following:

<a href="logout.php">Logout</a>

This was working fine. But later on I realised that I also have to clear localstorage maintained by using Javascript before logging out the user. So, I had to call the javascript function that clears the localstorage before calling the logout.php file. 

Javascript function for clearing the localstorage:

function ClearMyLocalStorage()
{
localStorage.clear();
}

I investigated two approaches to accomplish my task.

Approach 1:

<a href="logout.php" onclick="ClearMyLocalStorage()">

Approach 2:

<a href="javascript:;" onclick="ClearMyLocalStorage();">Logout</a>

And in your function you have to write like

function ClearMyLocalStorage()
{
    localStorage.clear();
    window.location.href = 'logout.php';
}

How to change InnerHTML of all the HTML Buttons in one go using jQuery?

How to change InnerHTML of all the HTML Buttons in one go using jQuery?

Suppose, I have 5 buttons on my page. How can I change the innerHTML of the buttons in one go using jQuery? I want that buttons having text "Clicked" should get changed to "Click me" when Change InnerHTML button is clicked. I will use jQuery to solve this problem. Refer the following example.

<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript">
function ChangeInnerHTML()
{
//Iterate all the buttons with innerHTML = "Clicked" in the DOM and set them to "Click me".
}
</script>
</head>
<body>
<button type="button" id="myButton1">Click me</button>
<button type="button" id="myButton2">Clicked</button>
<button type="button" id="myButton3">Click me</button>
<button type="button" id="myButton4">Clicked</button>
<button type="button" id="myButton5">Click me</button>

<button type="button" id="btnChangeInnerHTML"      onclick="ChangeInnerHTML()">Change InnerHTML</button>

</body>
 </html>

 There are many approaches for doing this task.

Approach 1:

 function ChangeInnerHTML() {
    $('button').each(function() {
        if ($.trim($(this).html()) == "Clicked") 
            $(this).html('Click me');
    });
}

Approach 2:

Use Attribute selector in jquery.

function ChangeInnerHTML() 
{
$("[id^=myButton]:contains('Clicked')").click(function() {
$(this).text("Click Me");

});
}

Approach 3:

function ChangeInnerHTML()
{
document.body.innerHTML=
document.body.innerHTML.replace(/Clicked/g,'Click me');
}

Approach 4:

Without jQuery

function ChangeInnerHTML() 
{
    var btns = document.querySelectorAll('button[id^=myButton]');
    for (var i = 0; i < btns.length; i++) {
        if (btns[i].innerHTML.trim() == 'Clicked') {
            btns[i].innerHTML = 'Click Me'
        }
    }
}

Approach 5:

This will change the innerHTML of all the buttons.

function ChangeInnerHTML()
{
    $("button[id*=myButton]").html("Click me");
}

Friday, April 4, 2014

How to return value from child window to parent window using window.open in Javascript?

How to return value from child window to parent window using window.open in Javascript?

It is very easy to return a value from a child window to parent window which has been opened from parent window using window.open method in Javascript. In many scenarios, it is possible to do some calculations on the child window and parent window need the result of that calculations to perform some task. So, let's try to resolve this problem.

In Parent Window

I have following Javascript function which will open a child window named childWin. I also have a function which will catch the value returned by the child window.

function openChildWin() 
{   
    var childWin = window.open("childWin.html", "_blank", "height=400, width=550, status=yes, toolbar=no, menubar=no, location=no,addressbar=no); 
}

function setValue(val1) 
{
   //you can use the value here which has been returned by your child window
}

ChildWin.html page

Following is my childWin HTML page. There is a button on this HTML page which when clicked will return a value to the parent window which has setValue function. Basically, child window is accessing parent's setValue function here. After this, child window is closed.

<!DOCTYPE html>
<html lang="en">
  <head>

<script type="text/javascript">

function OKClicked()
{
window.opener.setValue('Hello');; //I want to return true here
window.close(); //Close this child window  
}

</script>

  </head>
  <body>
<button type="button" id="OKButton" onclick="OKClicked()">Click ME</button>
  </body>
 </html>

How to pass a Javascript Array to PHP file using AJAX and JSON?

How to pass a Javascript Array to PHP file using AJAX and JSON?

I have an array in javascript and I need to pass this array to a PHP by using AJAX call to that PHP file. I will get this array in PHP file and assign this javascript array to PHP array. Then I will find out the count of that PHP array elements and return it back to the javascript. I will convert JS array in JSON format by JSON.stringify. This is a very simple example on how to pass javascript array to PHP asynchronously. You can perform a lot of operations on this array which you have passed to PHP file but for simplicity I am just returning its count. Let's have a look at the following code snippet.

Javascript Array

var myJSArray = new Array("Saab","Volvo","BMW");

ProcessAJAXRequest() function wil pass JS array to PHP file using AJAX request and will show count of array elements returned by PHP file.

function ProcessAJAXRequest()
{
    $.ajax
    ({
        type: "POST",
        url: "myphpfile.php",
        data: {"myJSArray" : JSON.stringify(myJSArray)},
        success: function (data) 
        {
            alert(data); //count of array elements
        }
    });
}

myphpfile.php

<?php 
    $myPHPArray = json_decode($_POST["myJSArray"]);
    echo count($myPHPArray);
 ?>

Tuesday, February 4, 2014

AngularJS vs Ember vs Backbone: Which Javascript Framework to choose for Front-end Web Development?

AngularJS vs Ember vs Backbone: Which Javascript Framework to choose for Front-end Web Development?

I have tried to compare three most widely used Javascript frameworks like AngularJS, Ember and Backbone in terms of their performance, model mutation, template engine, testability, easy to learn and implement etc. Which javascript framework to choose for front-end web development is mainly decided by the nature of your application, what functionalities do you want to achieve in your application and your hold on the Javascript framework. Let's try to understand the difference between the various features of AngularJS, Ember and Backbone.

1. Templates

Backbone: In backbone, you can choose your own template engine, no matter whether it’s String or DOM based. Usually people prefer handlebars.js, a string-based template library.

Ember: It uses built-in string-based templates (mandatory). Arguments in favor of string-based templates include “it’s faster” (debatable) and “theoretically, the server can render them too” (also debatable, as that’s only true if you can actually run all of your model code on the server, and nobody generally does that in practice).

AngularJS: Angular uses built-in DOM-based templates (mandatory). DOM-based templates means doing control flow (each, if, etc.) purely via bindings in your actual markup and not relying on any external library. Argument include “it’s faster” (debatable) and “the code is easier to read and write”

In AngularJS, the DOM structure is created on pageload. Suppose you have multiple templates in your page and you don’t want to show them at a time. In that case also you have to define those at page load lavel, if you use angular, which will unnecessary create few extra DOM elements. But in Ember you can insert dynamic templates as it uses string based templating method. So in this perspective Ember and Backbone’s string-based templating may go handy, but if you talk about data binding, DOM-based templates provides you better performance. According to the Angular developers’ team, in near future DOM-based templating will be natively supported on browsers and when this happens, Angular apps will run way too faster, so we should best prepare ourselves for the future by adopting it now. AngularJS is from Google, so they are already working on this with Chromium and standards bodies.

2. Model Mutation

Backbone & Ember: In model mutation both Backbone and Ember follows almost the same structure and flow. They use getters and setters to get or set a value and this is also an efficient way to learn the model change and accordingly reflect it to view. But while rendering the data elements, ember adds observers to each element. As the observers are heavy, so it makes the rendering process slower.

AngularJS:  Angular doesn’t use the traditional getters and setters like backbone and ember, rather it uses Dirty Checking to learn the model change, which is way too faster (according to the angular team).

AngularJS uses Dirty Checking, which is based on the lexical scoping in js and helps in garbage collection too. Not only that, angular lets all the model mutation to happen first and then inform all the listeners in a consistent state. This helps to prevent wrong data operations.

3. Performance

Performance is something, which you just can’t judge only basing on the pros and cons of the framework. Rather, it completely depends on your needs and the type of app you are developing. The key performance judging factors are given in the examples below.

Eg 1: Suppose, in your app, you are using huge number of data. So if you use ember, you will find the app is taking too much time to get loaded; and that’s because ember adds observers to each element. So this thing makes the rendering very slow in comparison with backbone and angular. But once the app is loaded, and you expecting your view to reflect the model change immediately; well angular will make you sad. Because, as it don’t have an observer attached with each element, so to learn the data change, the angular controller has to traverse the whole data model (dirty checking). But if your app doesn’t depend on fast data binding; rather you want your app to load faster, angular is the best option.

Eg 2: AngularJS is sort of a HTML compiler. It has the power to manipulate the normal behaviour of your HTML. Suppose, you are printing the data of your model one by one using {{#each}} helper in ember (actually in handlebars), or using the ‘For’ loop of backbone. In this case ember will run a loop to print them; and as you know, loops are always heavy and time consuming operations. But in a similar situation, angular’s ‘ng-repeat’ will fetch the data as a whole and will put it directly on your html. This is a much faster process.

Eg 3: Suppose your app is a continious animation based app, where you have to perform some animation to each element in your model (let your model has the instances of few html elements or something similar to that). So here, ember’s observers will be of no use; cause no matter what, you have to change the model and view continuously. So angular’s continuous checking or dirty checking may play a role for you here.

So, this is how, performance is a variable thing, which varies from projects to projects, scenarios to scenarios, environments, dependencies and many more. So only that framework can give you best performance which is the most compatible one to your app.

4. Learning & Development

Backbone: Basic backbone is very easy to learn, but while developing, you will find it was not enough. Because only using backbone you can’t structure your code much. It needs more libraries and templates to make a proper project.

Ember: Ember has more structured documents and it’s also not that tough to learn. Its implementation (with handlebars) is much similar to the other process and object oriented programming.

AngularJS: Angular is a little tricky, because it’s somewhat an extension of HTML. But once you get this html processing, it will become the simplest framework to learn.

AngularJSis comparatively simple to learn, and more simple to develop. A friend of mine made a widget on backbone, which was of more than 3800 lines. It has come down to 725 lines when rewritten in Angular. And the code was more structured and clean. Simplicity is one of the best plus points of Angular.

5. Testability

Testing is possible on all the frameworks, if you learn the right pattern to develop your project. Your modularity and ability of dependency injection are the key parts to have a testable code. And modularity and dependency injection are two of the major features of angular. Angular itself was built keeping the testing facility in mind. So I think, in testability angular is ahead of Backbone and Ember.

6. Projects point of view

While developing, or before starting the development of a project you need to keep in minds many points; and these really plays the role behind the selection of the framework.

There was a time when the codes of backbone seemed to be very clean and structured. But ember and angular showed the codes can be more cleaner and structured. Let’s watch these three frameworks as project developers point of view.

Backbone: Maximum people has worked with backbone; so it’s much easier to found an experienced backbone developer. There are lot of help available there in the net about backbone. It won’t cost you much to train your people. So in this point of view, backbone is good.

Ember: The best thing about ember is, if forces you to follow the ember way; and if you don’t, the app will never run. Though for beginners it will be a headache; but the best thing is; as everyone will follow the same way to develop the app, so it will be well structured and very very easy to maintain in future. Everyone is not a good coder; and humans always like shortcuts. So, if you are developing a huge project with lots of developers, they can’t code any logic wherever they want. They have to strictly follow the MVC structure and ember’s way of coding.

AngularJS: What if you don’t have much time to develop your project? Not much time to learn frameworks? Then you must go with the angular way. Angular also makes the code much more cleaner, structured and maintainable if the developer has knowledge of MVC development. It reduces the lines of codes like anything.

Conclusion

It’s not like a single framework will be always the best one. I’ve also given examples for that in this article. There are lot of factors you need to take care of before selecting the javascript framework for your application. I’m working in a travel service company right now and we selected Ember over Angular for our development, because it was more suitable to our previous architecture and widget based development. Similarly lot other environmental factors will come.

Every framework has its pros and cons. But what we need to consider is, the requirement list of our project and the adaptability of the framework on those requirements. But as an overall view, I’ve found out angular is very easy to learn (even a guy who didn’t work much with MVC and just knows simple HTML and javascript, can learn it very easily); it reduces the number of lines in your code more than backbone and ember; if your data model is not huge, it provides you fast rendering and execution; manipulates the DOM directly; makes your code testable and lot more. That is why I’m considering Angular a better option than Ember and Backbone generally.

Monday, February 3, 2014

Basic AngularJS Interview Questions and Answers for Front-end Web Developers

Basic AngularJS Interview Questions and Answers for Front-end Web Developers

AngularJS is widely known Javascript framework. If you are a front-end web developer preparing for AngularJS interview, following basic AngularJS interview questions and answers might help you little bit. Before going to AngularJS interview, you should know basic concepts and architecture of AngularJS, key features of AngularJS, how AngularJS is different from jQuery or other Javascript frameworks etc. Following basic AngularJS interview questions and answers will give you little insight of these concepts.

1. Why is this project called "AngularJS"? Why is the namespace called "ng"?

Because HTML has Angular brackets and "ng" sounds like "Angular".

2. Is AngularJS a library, framework, plugin or a browser extension?

AngularJS fits the definition of a framework the best, even though it's much more lightweight than a typical framework and that's why many confuse it with a library.

AngularJS is 100% JavaScript, 100% client side and compatible with both desktop and mobile browsers. So it's definitely not a plugin or some other native browser extension.

3. Why to choose AngularJS Javascript Framework for front-end web development?


4. What are the key features of AngularJS?

Scope

The job of the Scope is to detect changes to model objects and create an execution context for expressions. There is one root scope for the application (ng-app) with hierarchical children scopes. It marshals the model to the view and forwards events to the controller.

Controller

The Controller is responsible for construction of the model and connects it to the view (HTML). The scope sits between the controller and the view. Controllers should be straightforward and simply contain the business logic needed for a view. Generally you want thin controllers and rich services. Controllers can be nested and handle inheritance. The big difference in AngularJS from the other JavaScript frameworks is there is no DOM manipulation in controllers. It is something to unlearn when developing in AngularJS.

Model

In AngularJS, a Model is simply a JavaScript object. No need to extend anything or create any structure. This allows for nested models  - something that Backbone doesn’t do out-of-the-box.

View

The View is based on DOM objects, not on strings. The view is the HTML. HTML is declarative – well suited for UI design. The View should not contain any functional behavior. The flexibility here is to allow for multiple views per Controller.

Services

The Services in AngularJS are singletons that perform common tasks for web applications. If you need to share common functionality between Controllers, then use Services. Built-in AngularJS, Services start with a $. There are several ways to build a service: Service API, Factory API, or the $provide API.

Data Binding

Data Binding in AngularJS is a two-way binding between the View and the Model. Automatic synchronizing between views and data models makes this really easy (and straightforward) to use. Updating the model is reflected in View without any explicit JavaScript code to bind them together, or to add event listeners to reflect data changes.

Directives

Now this is cool. AngularJS allows you to use Directives to transform the DOM or to create new behavior. A directive allows you to extend the HTML vocabulary in a declarative fashion. The ‘ng’ prefix stands for built-in AngularJS directives. The App (ng-app), Model (ng-model), the Controller (ng-controller), etc. are built into the framework. AngularJS allows for building your own directives. Building directives is not extremely difficult, but not easy either. There are different things that can be done with them. Please check out AngularJS’s documentation on directives.

Filters

The Filters in AngularJS perform data transformation. They can be used to do formatting (like I did in my Directives example with padding zeros), or they can be used to do filter results (think search).

Validation

AngularJS has some built-in validation around HTML5 input variables (text, number, URL, email, radio, checkbox) and some directives (required, pattern, minlength, maxlength, min, max). If you want to create your own validation, it is just as simple as creating a directive to perform your validation.

Testable

Testing is a big concern for enterprise applications. There are several different ways to write and run tests against JavaScript code, thus against AngularJS. The developers at AngularJS advocate using Jasmine tests ran using Testacular. I have found this method of testing very straightforward and, while writing tests may not be the most enjoyable, it is just as importable as any other piece of developing an application.

5. What is a scope in AngularJS?

scope is an object that refers to the application model. It is the glue between application controller and the view. Both the controllers and directives have reference to the scope, but not with each other. It is an execution context for expressions and arranged in hierarchical structure. Scopes can watch expressions and propagate events.

6. Can you explain the concept of scope hierarchy? How many scopes can an application have?

Each Angular application has exactly one root scope, but may have several child scopes. The application can have multiple scopes, because child controllers and some directives create new child scopes. When new scopes are created, they are added as children of their parent scope. This creates a hierarchical structure similar to the DOM where they're attached.

When Angular evaluates a bound variable like say {{firstName}}, it first looks at the scope associated with the given element for the firstName property. If no such property is found, it searches the parent scope and so on until the root scope is reached. In JavaScript this behaviour is known as prototypical inheritance, and child scopes prototypically inherit from their parents. The reverse is not true. i.e. the parent can't see it's children's bound properties.

7. Is AngularJS a templating system?

At the highest level, Angular does look like a just another templating system. But there is one important reason why the Angular templating system is different, that makes it very good fit for application development: bidirectional data binding. The template is compiled in the browser and the compilation step produces a live view. This means you, the developers, don't need to write code to constantly sync the view with the model and the model with the view as in other templating systems.

8. Do I need to worry about security holes in AngularJS?

Like any other technology, AngularJS is not impervious to attack. Angular does, however, provide built-in protection from basic security holes including cross-site scripting and HTML injection attacks. AngularJS does round-trip escaping on all strings for you and even offers XSRF protection for server-side communication.

AngularJS was designed to be compatible with other security measures like Content Security Policy (CSP), HTTPS (SSL/TLS) and server-side authentication and authorization that greatly reduce the possible attack vectors and we highly recommended their use.

9. What's Angular's performance like?

The startup time heavily depends on your network connection, state of the cache, browser used and available hardware, but typically we measure bootstrap time in tens or hundreds of milliseconds.

The runtime performance will vary depending on the number and complexity of bindings on the page as well as the speed of your backend (for apps that fetch data from the backend). Just for an illustration we typically build snappy apps with hundreds or thousands of active bindings.

10. Does Angular use the jQuery library?

Yes, Angular can use jQuery if it's present in your app when the application is being bootstrapped. If jQuery is not present in your script path, Angular falls back to its own implementation of the subset of jQuery that we call jQLite.

Due to a change to use on()/off() rather than bind()/unbind(), Angular 1.2 only operates with jQuery 1.7.1 or above.

11. What are the key differences between AngularJS and jQuery?


12. How will you compare AngularJS with other Javascript frameworks like Ember and Backbone?

Read complete answer

13. How will you display different images based on the status being red, amber, or green?

Use the ng-switch and ng-switch-when directives as shown below.

<div ng-switch on="account.status">
 <div ng-switch-when="AMBER">
  <img class="statusIcon"
   src='apps/dashboard/amber-dot.jpg' />
 </div>
 <div ng-switch-when="GREEN">
  <img class="statusIcon"
   src='apps/dashboard/green-dot.jpg' />
 </div>
 <div ng-switch-when="RED">
  <img class="statusIcon"
   src='apps/dashboard/red-dot.jpg' />
 </div>
</div>

14. How will you initialize a select box with options on page load?

Use the ng-init directive.

<div ng-controller="apps/dashboard/account" ng-switch
 on="!!accounts" ng-init="loadData()">

15. How will you show/hide buttons and enable/disable buttons conditionally?

Using the ng-show and ng-disabled directives.

<div class="dataControlPanel"
    ng-show="accounts.releasePortfolios">
     
    <div class="dataControlButtons">
     <button class="btn btn-primary btn-small"
      ng-click="saveComments()" ng-disabled="disableSaveButton">Save</button>
     <button class="btn btn-primary btn-small"
      ng-click="releaseRun()" ng-disabled="disableReleaseButton">Release</button>
    </div>
</div>

16. How will you loop through a collection and list each item?

Using the ng-repeat directive.

<table
  class="table table-bordered table-striped table-hover table-fixed-head portal-data-table">
  <thead>
   <tr>
    <th>account</th>
    <th>Difference</th>
    <th>Status</th>
   </tr>
  </thead>
  <tbody>
   <tr
    ng-repeat="account in acounts">
    <td width="40%">{{account.accountCode}}</td>
    <td width="30%" style="text-align: right">{{account.difference
     | currency: ""}}</td>
    <td width="30%">

     <div ng-switch on="account.status">
      <div ng-switch-when="AMBER">
       <img class="statusIcon"
        src='apps/dashboard/amber-dot.jpg' />
      </div>
      <div ng-switch-when="GREEN">
       <img class="statusIcon"
        src='apps/dashboard/green-dot.jpg' />
      </div>
      <div ng-switch-when="RED">
       <img class="statusIcon"
        src='apps/dashboard/red-dot.jpg' />
      </div>
     </div>

    </td>
   </tr>
  </tbody>
</table>

17. How will you add options to a select box?

Using the ng-options and ng-model directives.

<fieldset>
 <dl class="control-group">
  <dt>
   <label for="cientId">
    <h4>Client Id:</h4>
   </label>
  </dt>
  <dd>
   <select id="cientId" class="input-xlarge" ng-model="clientId"
    ng-options="reportClient.clientId as reportClient.clientId  for reportClient in reportClients "
    ng-click="getReportParams()" ng-change="getValuationDates()" />
  </dd>
 </dl>
 <dl class="control-group">
  <dt>
   <label for="valuationDate">
    <h4>
     Valuation Date <small>(dd/mm/yyyy)</small>
    </h4>
   </label>
  </dt>
  <dd>
   <select id="valuationDate" class="input-xlarge"
    ng-model="valuationDate"
    ng-options="reportdate for reportdate in reportDates" />
  </dd>
 </dl>
</fieldset>

18. How will you display inprogress revolving image to indicate that RESTful data is bing loaded?

<div ng-show="loading">
 <img class="loading" src="portal/images/loading_32.gif" />
</div>

 $scope.loadReportData = function($http) {
 $scope.loading = true;  // start spinng the image
 $http(
   {
    method : 'GET',
    url : propertiesService.get('restPath')
      + '/myapp/portfolio/'
      + $scope.clientId
      + '/'
      + dateService
        .userToRest($scope.reportDate),
    cacheBreaker : true
   }).success(
   function(data, config) {
    $scope.reportData = data;
    portal.log('reportData: ',
      $scope.reportData);
    $scope.loading = false;   // stop spinning the image
   }).error(
   function(data, status, headers, config) {
    if(data.errorMsg != null) {
     $scope.httpError = data.errorMsg;
    }
    else {
    $scope.httpError = "Error retrieving data from " + errorService
      .getApacheErrorTitleMessage(status,
        data, config);
       }
    $scope.loading = false;  // stop spinning the image
   });

};

AngularJS vs jQuery: Difference between AngularJS and jQuery: Never mix up AngularJS and jQuery code

AngularJS vs jQuery: Difference between AngularJS and jQuery: Never mix up AngularJS and jQuery code

AngularJS and jQuery are the Javascript frameworks and are different with each other, so never mix up the AngularJS and jQuery code in your project. Use only one Javascript framework at a time. If you are starting a new project, must consider AngularJS over jQuery. If you are a experienced jQuery developer, then you have to invest some time to work in AngularJS way. There are a lot of difference between AngularJS and jQuery.

1. Web designing approach in jQuery and AngularJS

In jQuery, you design a page, and then you make it dynamic. This is because jQuery was designed for augmentation and has grown incredibly from that simple premise.

But in AngularJS, you must start from the ground up with your architecture in mind. Instead of starting by thinking "I have this piece of the DOM and I want to make it do X", you have to start with what you want to accomplish, then go about designing your application, and then finally go about designing your view.

2. Don't augment jQuery with AngularJS

Similarly, don't start with the idea that jQuery does X, Y, and Z, so I'll just add AngularJS on top of that for models and controllers. This is really tempting when you're just starting out, which is why I always recommend that new AngularJS developers don't use jQuery at all, at least until they get used to doing things the "Angular Way".

I've seen many developers here and on the mailing list create these elaborate solutions with jQuery plugins of 150 or 200 lines of code that they then glue into AngularJS with a collection of callbacks and $applys that are confusing and convoluted; but they eventually get it working! The problem is that in most cases that jQuery plugin could be rewritten in AngularJS in a fraction of the code, where suddenly everything becomes comprehensible and straightforward.

The bottom line is this: when solutioning, first "think in AngularJS"; if you can't think of a solution, ask the community; if after all of that there is no easy solution, then feel free to reach for the jQuery. But don't let jQuery become a crutch or you'll never master AngularJS.

3. Always think in terms of architecture

First know that single-page applications are applications. They're not webpages. So we need to think like a server-side developer in addition to thinking like a client-side developer. We have to think about how to divide our application into individual, extensible, testable components.

So then how do you do that? How do you "think in AngularJS"? Here are some general principles, contrasted with jQuery.

The view is the "official record"

In jQuery, we programmatically change the view. We could have a dropdown menu defined as a ul like so:

<ul class="main-menu">
    <li class="active">
        <a href="#/home">Home</a>
    </li>
    <li>
        <a href="#/menu1">Menu 1</a>
        <ul>
            <li><a href="#/sm1">Submenu 1</a></li>
            <li><a href="#/sm2">Submenu 2</a></li>
            <li><a href="#/sm3">Submenu 3</a></li>
        </ul>
    </li>
    <li>
        <a href="#/home">Menu 2</a>
    </li>
</ul>

In jQuery, in our application logic, we would activate it with something like:

$('.main-menu').dropdownMenu();

When we just look at the view, it's not immediately obvious that there is any functionality here. For small applications, that's fine. But for non-trivial applications, things quickly get confusing and hard to maintain.

In AngularJS, though, the view is the official record of view-based functionality. Our ul declaration would look like this instead:

<ul class="main-menu" dropdown-menu>
    ...
</ul>

These two do the same thing, but in the AngularJS version anyone looking at the template knows what's supposed to happen. Whenever a new member of the development team comes on board, he can look at this and then know that there is a directive called dropdownMenu operating on it; he doesn't need to intuit the right answer or sift through any code. The view told us what was supposed to happen. Much cleaner.

Developers new to AngularJS often ask a question like: how do I find all links of a specific kind and add a directive onto them. The developer is always flabbergasted when we reply: you don't. But the reason you don't do that is that this is like half-jQuery, half-AngularJS, and no good. The problem here is that the developer is trying to "do jQuery" in the context of AngularJS. That's never going to work well. The view is the official record. Outside of a directive (more on this below), you never, ever, never change the DOM. And directives are applied in the view, so intent is clear.

Remember: don't design, and then mark up. You must architect, and then design.

Data binding

This is by far one of the most awesome features of AngularJS and cuts out a lot of the need to do the kinds of DOM manipulations I mentioned in the previous section. AngularJS will automatically update your view so you don't have to! In jQuery, we respond to events and then update content. Something like:

$.ajax({
  url: '/myEndpoint.json',
  success: function ( data, status ) {
    $('ul#log').append('<li>Data Received!</li>');
  }
});

For a view that looks like this:

<ul class="messages" id="log">
</ul>

Apart from mixing concerns, we also have the same problems of signifying intent that I mentioned before. But more importantly, we had to manually reference and update a DOM node. And if we want to delete a log entry, we have to code against the DOM for that too. How do we test the logic apart from the DOM? And what if we want to change the presentation?

This a little messy and a trifle frail. But in AngularJS, we can do this:

$http( '/myEndpoint.json' ).then( function ( response ) {
    $scope.log.push( { msg: 'Data Received!' } );
});

And our view can look like this:

<ul class="messages">
    <li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>

But for that matter, our view could look like this:

<div class="messages">
    <div class="alert" ng-repeat="entry in log">
        {{ entry.msg }}
    </div>
</div>

And now instead of using an unordered list, we're using Bootstrap alert boxes. And we never had to change the controller code! But more importantly, no matter where or how the log gets updated, the view will change too. Automatically. Neat!

Though I didn't show it here, the data binding is two-way. So those log messages could also be editable in the view just by doing this: 
<input ng-model="entry.msg" />. 
And there was much rejoicing.

Distinct model layer

In jQuery, the DOM is kind of like the model. But in AngularJS, we have a separate model layer that we can manage in any way we want, completely independently from the view. This helps for the above data binding, maintains separation of concerns, and introduces far greater testability. Other answers mentioned this point, so I'll just leave it at that.

Separation of concerns

And all of the above tie into this over-arching theme: keep your concerns separate. Your view acts as the official record of what is supposed to happen (for the most part); 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. This was also mentioned in other answers, and the only thing I would add pertains to testability, which I discuss in another section below.

Dependency injection

To help us out with separation of concerns is dependency injection (DI). If you come from a server-side language (from Java to PHP) you're probably familiar with this concept already, but if you're a client-side guy coming from jQuery, this concept can seem anything from silly to superfluous to hipster. But it's not. 

From a broad perspective, DI means that you can declare components very freely and then from any other component, just ask for an instance of it and it will be granted. You don't have to know about loading order, or file locations, or anything like that. The power may not immediately be visible, but I'll provide just one (common) example: testing.

Let's say in our application, we require a service that implements server-side storage through a REST API and, depending on application state, local storage as well. When running tests on our controllers, we don't want to have to communicate with the server - we're testing the controller, after all. We can just add a mock service of the same name as our original component, and the injector will ensure that our controller gets the fake one automatically - our controller doesn't and needn't know the difference.

4. Test-driven development 

This is really part of section 3 on architecture, but it's so important that I'm putting it as its own top-level section.

Out of all of the many jQuery plugins you've seen, used, or written, how many of them had an accompanying test suite? Not very many because jQuery isn't very amenable to that. But AngularJS is.

In jQuery, the only way to test is often to create the component independently with a sample/demo page against which our tests can perform DOM manipulation. So then we have to develop a component separately and then integrate it into our application. How inconvenient! So much of the time, when developing with jQuery, we opt for iterative instead of test-driven development. And who could blame us?

But because we have separation of concerns, we can do test-driven development iteratively in AngularJS! For example, let's say we want a super-simple directive to indicate in our menu what our current route is. We can declare what we want in our view:

<a href="/hello" when-active>Hello</a>

Okay, now we can write a test:

it( 'should add "active" when the route changes', inject(function() {
    var elm = $compile( '<a href="/hello" when-active>Hello</a>' )( $scope );

    $location.path('/not-matching');
    expect( elm.hasClass('active') ).toBeFalsey();

    $location.path( '/hello' );
    expect( elm.hasClass('active') ).toBeTruthy();
}));

We run our test and confirm that it fails. So now we can write our directive:

.directive( 'whenActive', function ( $location ) {
    return {
        scope: true,
        link: function ( scope, element, attrs ) {
            scope.$on( '$routeChangeSuccess', function () {
                if ( $location.path() == element.attr( 'href' ) ) {
                    element.addClass( 'active' );
                }
                else {
                    element.removeClass( 'active' );
                }
            });
        }
    };
});

Our test now passes and our menu performs as requested. Our development is both iterative and test-driven. 

5. Conceptually, directives are not packaged jQuery

You'll often hear "only do DOM manipulation in a directive". This is a necessity. Treat it with due deference!

But let's dive a little deeper...

Some directives just decorate what's already in the view (think ngClass) and therefore sometimes do DOM manipulation straight away and then are basically done. But if a directive is like a "widget" and has a template, it should also respect separation of concerns. That is, the template too should remain largely independent from its implementation in the link and controller functions.

AngularJS comes with an entire set of tools to make this very easy; with ngClass we can dynamically update the class; ngBind allows two-way data binding; ngShow and ngHide programmatically show or hide an element; and many more - including the ones we write ourselves. In other words, we can do all kinds of awesomeness without DOM manipulation. The less DOM manipulation, the easier directives are to test, the easier they are to style, the easier they are to change in the future, and the more re-usable and distributable they are.

I see lots of developers new to AngularJS using directives as the place to throw a bunch of jQuery. In other words, they think "since I can't do DOM manipulation in the controller, I'll take that code put it in a directive". While that certainly is much better, it's often still wrong.

Think of the logger we programmed in section 3. Even if we put that in a directive, we still want to do it the "Angular Way". It still doesn't take any DOM manipulation! There are lots of times when DOM manipulation is necessary, but it's a lot rarer than you think! Before doing DOM manipulation anywhere in your application, ask yourself if you really need to. There might be a better way.

Here's a quick example that shows the pattern I see most frequently. We want a toggleable button. (Note: this example is a little contrived and a skosh verbose to represent more complicated cases that are solved in exactly the same way.)

.directive( 'myDirective', function () {
    return {
        template: '<a class="btn">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            var on = false;

            $(element).click( function () {
                if ( on ) {
                    $(element).removeClass( 'active' );
                }
                else {
                    $(element).addClass( 'active' );
                }

                on = !on;
            });
        }
    };
});

There are a few things wrong with this. First, jQuery was never necessary. There's nothing we did here that needed jQuery at all! Second, even if we already have jQuery on our page, there's no reason to use it here; we can simply use angular.element and our component will still work when dropped into a project that doesn't have jQuery. Third, even assuming jQuery was required for this directive to work, jqLite (angular.element) will always use jQuery if it was loaded! So we needn't use the $ - we can just use angular.element. Fourth, closely related to the third, is that jqLite elements needn't be wrapped in $ - the element that is passed to the link function would already be a jQuery element! And fifth, which we've mentioned in previous sections, why are we mixing template stuff into our logic?

This directive can be rewritten (even for very complicated cases!) much more simply like so:

.directive( 'myDirective', function () {
    return {
        scope: true,
        template: '<a class="btn" ng-class="{active: on}" ng-click="toggle()">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            scope.on = false;

            scope.toggle = function () {
                scope.on = !scope.on;
            };
        }
    };
});

Again, the template stuff is in the template, so you (or your users) can easily swap it out for one that meets any style necessary, and the logic never had to be touched. 

And there are still all those other benefits, like testing - it's easy! No matter what's in the template, the directive's internal API is never touched, so refactoring is easy. You can change the template as much as you want without touching the directive. And no matter what you change, your tests still pass.

So if directives aren't just collections of jQuery-like functions, what are they? Directives are actually extensions of HTML. If HTML doesn't do something you need it to do, you write a directive to do it for you, and then use it just as if it was part of HTML.

Put another way, if AngularJS doesn't do something out of the box, think how the team would accomplish it to fit right in with ngClick, ngClass, et al.

Summary

Don't even use jQuery. Don't even include it. It will hold you back. And when you come to a problem that you think you know how to solve in jQuery already, before you reach for the $, try to think about how to do it within the confines the AngularJS. If you don't know, ask! 19 times out of 20, the best way to do it doesn't need jQuery and to try to solve it with jQuery results in more work for you.