javascript - tutorial - thinking in angular 2

“Thinking in AngularJS” if I have a jQuery background? (10)

Suppose I'm familiar with developing client-side applications in jQuery, but now I'd like to start using AngularJS. Can you describe the paradigm shift that is necessary? Here are a few questions that might help you frame an answer:

  • How do I architect and design client-side web applications differently? What is the biggest difference?
  • What should I stop doing/using; What should I start doing/using instead?
  • Are there any server-side considerations/restrictions?

I'm not looking for a detailed comparison between jQuery and AngularJS.

Can you describe the paradigm shift that is necessary?

Imperative vs Declarative

With jQuery you tell the DOM what needs to happen, step by step. With AngularJS you describe what results you want but not how to do it. More on this here. Also, check out Mark Rajcok's answer.

How do I architect and design client-side web apps differently?

AngularJS is an entire client-side framework that uses the MVC pattern (check out their graphical representation). It greatly focuses on separation of concerns.

What is the biggest difference? What should I stop doing/using; what should I start doing/using instead?

jQuery is a library

AngularJS is a beautiful client-side framework, highly testable, that combines tons of cool stuff such as MVC, dependency injection, data binding and much more.

It focuses on separation of concerns and testing (unit testing and end-to-end testing), which facilitates test-driven development.

The best way to start is going through their awesome tutorial. You can go through the steps in a couple of hours; however, in case you want to master the concepts behind the scenes, they include a myriad of reference for further reading.

Are there any server-side considerations/restrictions?

You may use it on existing applications where you are already using pure jQuery. However, if you want to fully take advantage of the AngularJS features you may consider coding the server side using a RESTful approach.

Doing so will allow you to leverage their resource factory, which creates an abstraction of your server side RESTful API and makes server-side calls (get, save, delete, etc.) incredibly easy.

1. Don't design your page, and then change it with DOM manipulations

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>
        <a href="#/menu1">Menu 1</a>
            <li><a href="#/sm1">Submenu 1</a></li>
            <li><a href="#/sm2">Submenu 2</a></li>
            <li><a href="#/sm3">Submenu 3</a></li>
        <a href="#/home">Menu 2</a>

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


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>

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, she can look at this and then know that there is a directive called dropdownMenu operating on it; she 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:

  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">

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>

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

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

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.

Speaking of testing...

4. Test-driven development - always

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 the view of our application:

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

Okay, now we can write a test for the non-existent when-active directive:

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

    expect( elm.hasClass('active') ).toBeFalsey();

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

And when we run our test, we can confirm that it fails. Only now should we create 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. Wicked-cool.

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; ngModel 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 () {
                on = !on;
                $(element).toggleClass('active', on);

There are a few things wrong with this:

  1. First, jQuery was never necessary. There's nothing we did here that needed jQuery at all!
  2. 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.
  3. 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.
  4. 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!
  5. 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. Reusability - boom!

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.


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.


jQuery makes ridiculously long JavaScript commands like getElementByHerpDerp shorter and cross-browser.


AngularJS allows you to make your own HTML tags/attributes that do things which work well with dynamic web applications (since HTML was designed for static pages).


Saying "I have a jQuery background how do I think in AngularJS?" is like saying "I have an HTML background how do I think in JavaScript?" The fact that you're asking the question shows you most likely don't understand the fundamental purposes of these two resources. This is why I chose to answer the question by simply pointing out the fundamental difference rather than going through the list saying "AngularJS makes use of directives whereas jQuery uses CSS selectors to make a jQuery object which does this and that etc....". This question does not require a lengthy answer.

jQuery is a way to make programming JavaScript in the browser easier. Shorter, cross-browser commands, etc.

AngularJS extends HTML, so you don't have to put <div> all over the place just to make an application. It makes HTML actually work for applications rather than what it was designed for, which is static, educational web pages. It accomplishes this in a roundabout way using JavaScript, but fundamentally it is an extension of HTML, not JavaScript.

Imperative → declarative

In jQuery, selectors are used to find DOM elements and then bind/register event handlers to them. When an event triggers, that (imperative) code executes to update/change the DOM.

In AngularJS, you want to think about views rather than DOM elements. Views are (declarative) HTML that contain AngularJS directives. Directives set up the event handlers behind the scenes for us and give us dynamic databinding. Selectors are rarely used, so the need for IDs (and some types of classes) is greatly diminished. Views are tied to models (via scopes). Views are a projection of the model. Events change models (that is, data, scope properties), and the views that project those models update "automatically."

In AngularJS, think about models, rather than jQuery-selected DOM elements that hold your data. Think about views as projections of those models, rather than registering callbacks to manipulate what the user sees.

Separation of concerns

jQuery employs unobtrusive JavaScript - behavior (JavaScript) is separated from the structure (HTML).

AngularJS uses controllers and directives (each of which can have their own controller, and/or compile and linking functions) to remove behavior from the view/structure (HTML). Angular also has services and filters to help separate/organize your application.

See also https://.com/a/14346528/215945

Application design

One approach to designing an AngularJS application:

  1. Think about your models. Create services or your own JavaScript objects for those models.
  2. Think about how you want to present your models -- your views. Create HTML templates for each view, using the necessary directives to get dynamic databinding.
  3. Attach a controller to each view (using ng-view and routing, or ng-controller). Have the controller find/get only whatever model data the view needs to do its job. Make controllers as thin as possible.

Prototypal inheritance

You can do a lot with jQuery without knowing about how JavaScript prototypal inheritance works. When developing AngularJS applications, you will avoid some common pitfalls if you have a good understanding of JavaScript inheritance. Recommended reading: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

Actually, if you're using AngularJS, you don't need jQuery anymore. AngularJS itself has the binding and directive, which is a very good "replacement" for most things you can do with jQuery.

I usually develop mobile applications using AngularJS and Cordova. The ONLY thing from jQuery I needed is the Selector.

By googling, I see that there is a standalone jQuery selector module out there. It's Sizzle.

And I decided to make a tiny code snippet that help me quickly start a website using AngularJS with the power of jQuery Selector (using Sizzle).

I shared my code here:

As a JavaScript MV* beginner and purely focusing on the application architecture (not the server/client-side matters), I would certainly recommend the following resource (which I am surprised wasn't mentioned yet): JavaScript Design Patterns, by Addy Osmani, as an introduction to different JavaScript Design Patterns. The terms used in this answer are taken from the linked document above. I'm not going to repeat what was worded really well in the accepted answer. Instead, this answer links back to the theoretical backgrounds which power AngularJS (and other libraries).

Like me, you will quickly realize that AngularJS (or Ember.js, Durandal, & other MV* frameworks for that matter) is one complex framework assembling many of the different JavaScript design patterns.

I found it easier also, to test (1) native JavaScript code and (2) smaller libraries for each one of these patterns separately before diving into one global framework. This allowed me to better understand which crucial issues a framework adresses (because you are personally faced with the problem).

For example:

  • JavaScript Object-oriented Programming (this is a Google search link). It is not a library, but certainly a prerequisite to any application programming. It taught me the native implementations of the prototype, constructor, singleton & decorator patterns
  • jQuery/ Underscore for the facade pattern (like WYSIWYG's for manipulating the DOM)
  • Prototype.js for the prototype/ constructor/ mixin pattern
  • RequireJS/ Curl.js for the module pattern/ AMD
  • KnockoutJS for the observable, publish/subscribe pattern

NB: This list is not complete, nor 'the best libraries'; they just happen to be the libraries I used. These libraries also include more patterns, the ones mentioned are just their main focuses or original intents. If you feel something is missing from this list, please do mention it in the comments, and I will be glad to add it.

Listen to the podcast JavaScript Jabber: Episode #32 that features the original creators of AngularJS: Misko Hevery & Igor Minar. They talk a lot about what it's like to come to AngularJS from other JavaScript backgrounds, especially jQuery.

One of the points made in the podcast made a lot of things click for me with respects to your question:

MISKO: [...] one of the things we thought about very hardly in Angular is, how do we provide lots of escape hatches so that you can get out and basically figure out a way out of this. So to us, the answer is this thing called “Directives”. And with directives, you essentially become a regular little jQuery JavaScript, you can do whatever you want.

IGOR: So think of directive as the instruction to the compiler that tells it whenever you come across this certain element or this CSS in the template, and you keep this kind of code and that code is in charge of the element and everything below that element in the DOM tree.

A transcript of the entire episode is available at the link provided above.

So, to directly answer your question: AngularJS is -very- opinionated and is a true MV* framework. However, you can still do all of the really cool stuff you know and love with jQuery inside of directives. It's not a matter of "How do I do what I used to in jQuery?" as much as it's a matter of "How do I supplement AngularJS with all of the stuff I used to do in jQuery?"

It's really two very different states of mind.

They're apples and oranges. You don't want to compare them. They're two different things. AngularJs has already jQuery lite built in which allows you to perform basic DOM manipulation without even including the full blown jQuery version.

jQuery is all about DOM manipulation. It solves all the cross browser pain otherwise you will have to deal with but it's not a framework that allows you to divide your app into components like AngularJS.

A nice thing about AngularJs is that it allows you to separate/isolate the DOM manipulation in the directives. There are built-in directives ready for you to use such as ng-click. You can create your own custom directives that will contain all your view logic or DOM manipulation so you don't end up mingle DOM manipulation code in the controllers or services that should take care of the business logic.

Angular breaks down your app into - Controllers - Services - Views - etc.

and there is one more thing, that's the directive. It's an attribute you can attach to any DOM element and you can go nuts with jQuery within it without worrying about your jQuery ever conflicts with AngularJs components or messes up with its architecture.

I heard from a meetup I attended, one of the founders of Angular said they worked really hard to separate out the DOM manipulation so do not try to include them back in.

To describe the "paradigm shift", I think a short answer can suffice.

AngularJS changes the way you find elements

In jQuery, you typically use selectors to find elements, and then wire them up:
$('#id .class').click(doStuff);

In AngularJS, you use directives to mark the elements directly, to wire them up:
<a ng-click="doStuff()">

AngularJS doesn't need (or want) you to find elements using selectors - the primary difference between AngularJS's jqLite versus full-blown jQuery is that jqLite does not support selectors.

So when people say "don't include jQuery at all", it's mainly because they don't want you to use selectors; they want you to learn to use directives instead. Direct, not select!

jQuery is a DOM manipulation library.

AngularJS is an MV* framework.

In fact, AngularJS is one of the few JavaScript MV* frameworks (many JavaScript MVC tools still fall under the category library).

Being a framework, it hosts your code and takes ownership of decisions about what to call and when!

AngularJS itself includes a jQuery-lite edition within it. So for some basic DOM selection/manipulation, you really don't have to include the jQuery library (it saves many bytes to run on the network.)

AngularJS has the concept of "Directives" for DOM manipulation and designing reusable UI components, so you should use it whenever you feel the need of doing DOM manipulation related stuff (directives are only place where you should write jQuery code while using AngularJS).

AngularJS involves some learning curve (more than jQuery :-).

-->For any developer coming from jQuery background, my first advice would be to "learn JavaScript as a first class language before jumping onto a rich framework like AngularJS!" I learned the above fact the hard way.

Good luck.