angular js ng book preview book

Upload: sandeepkul88

Post on 04-Jun-2018

216 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/13/2019 Angular JS Ng Book Preview book

    1/13

  • 8/13/2019 Angular JS Ng Book Preview book

    2/13

  • 8/13/2019 Angular JS Ng Book Preview book

    3/13

    Tweet This Book!

    Please help Ari Lerner by spreading the word about this book onTwitter!

    The suggested tweet for this book is:

    I just bought #ng-book, the beginners guide to AngularJS! Im ready to build advanced, modern

    webapps!

    The suggested hashtag for this book is#ngbook.

    Find out what other people are saying about the book by clicking on this link to search for this

    hashtag on Twitter:

    https://twitter.com/search?q=#ngbook

    https://twitter.com/search?q=%23ngbookhttps://twitter.com/search?q=%23ngbookhttp://twitter.com/
  • 8/13/2019 Angular JS Ng Book Preview book

    4/13

    Also ByAri LernerThe Rails 4 Way

    Riding Rails with AngularJS

    http://leanpub.com/angularjs-railshttp://leanpub.com/tr4whttp://leanpub.com/u/auser
  • 8/13/2019 Angular JS Ng Book Preview book

    5/13

    Contents

    Promises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

    Whats a promise? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

    Why promises? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

    Promises in Angular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

    chaining requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

  • 8/13/2019 Angular JS Ng Book Preview book

    6/13

    PromisesAngulars event system (we talk about this in-depth in theunder the hood) provides a lot of power

    to our Angular apps. One of the most powerful features that it enables is automatic resolution of

    promises.

    Whats a promise?

    Promises are a method of resolving a value or not in an asynchronous manner. Promises are objects

    that represent the return value or a thrown exception that a function may eventually provide.

    Promises are incredibly useful in dealing with remote objects and we can think of them as a proxy

    for them.

    Traditionally, javascript uses closures, or callbacks to respond with meaningful data that is not

    available in a synchronous time, such as XHR requests after a page has loaded. Rather than

    depending upon a callback to be fired, we can interact with the data instead as though it has already

    returned.

    Callbacks have worked for a long time, but the developer suffers a lot when using them. They have

    no consistency in callbacks, no guaranteed call, steal code flow when callbacks depend upon other

    callbacks, and in general make debugging incredibly difficult. At every step of the way, we have to

    deal withexplicitlyhandling errors.Instead of fire-and-hopefully-get-a-callback-run when executing asynchronous methods, promises

    offer a different abstraction. They return a promise object.

    For example, in traditional callback code we might have a method that sends a message from one

    user to one of their friends.

    1 // Sample callback code

    2 User.get(fromId, {

    3 success: function(err, user) {

    4 if (err) return {error: err};

    5 user.friends.find(toId, function(err, friend) {

    6 if (err) return {error: err};

    7 user.sendMessage(friend, message, callback);

    8 });

    9 },

    10 failure: function(err) {

    11 return {error: err}

    http://-/?-
  • 8/13/2019 Angular JS Ng Book Preview book

    7/13

    Promises 2

    12 }

    13 });

    This callback-pyramid is already getting out of hand and we havent included any robust error

    handling code either. Additionally, well need to know the order in which the arguments are called

    from within our callback.

    The promised-based version of the previous code might look something closer to:

    1 User.get(fromId)

    2 .then(function(user) {

    3 return user.friends.find(toId);

    4 }, function(err) {

    5 // We couldn't find the user

    6 })

    7 .then(function(friend) {

    8 return user.sendMessage(friend, message);

    9 }, function(err) {

    10 // The user's friend resulted in an error

    11 })

    12 .then(function(success) {

    13 // user was sent the message

    14 }, function(err) {

    15 // An error occurred

    16 });

    Not only is this more readable, but it is also much easier to grok. We can also guarantee that the

    callback will resolve to a single value, rather than dealing with the callback interface.

    Notice, in the first example we have to handle errors differently to non-errors and well need to

    make sure that using callbacks to handle errors will all need to implement the same API (usually

    with(err, data)being the usual method signature).

    In the second example, we handle the success and error in the same way. Our resultant object will

    receive the error in the usual manner. Additionally, since the promise API is specific about resolving

    or rejecting promises, we dont have to worry about our methods implementing a different method

    signature.

    Why promises?

    Although a bi-product of promises is the fact that we can get away from callback hell, the point of

    promises is to make asynchronous functions look more like synchronous ones. With synchronous

    functions, we can capture both return values and exception values as expected.

  • 8/13/2019 Angular JS Ng Book Preview book

    8/13

    Promises 3

    We can capture errors at any point of the process and bypass future code that relies upon the error

    of that process. We do all this without thinking about the benefits of this synchronous code as its

    the nature of it.

    Thus, the point of using promises is to regain the ability to do functional composition and errorbubbling while maintaining the ability of the code to run asynchronously.

    Promises arefirst-classobjects and carry with them a few guarantees:

    Only one resolve or reject will ever be called

    resolve will be called with a single fulfillment value

    reject will only be called with a single rejection reason

    If the promise has been resolved or rejected, any handlers depending upon them will still be

    called

    Handlers will always be called asynchronously

    Additionally, we can also chain promises and allow the code to process as it will normally would

    run. Exceptions from one promise bubble up through the entire promise chain.

    They are always asynchronous, so we can use them in the flow of our code without worry that they

    will block the rest of the app.

    Promises in Angular

    Angulars event-loop gives angular the unique ability to resolve promises in its $rootScope.$evalAsync

    stage (seeunder the hood for more detail on the run loop). The promises will sit inert until the$digestrun loop finishes.

    This allows for Angular to turn the results of a promise into the view without any extra work. It

    enables us to assign the result of an XHR call directly to a property on a $scopeobject and think

    nothing of it.

    Lets build an example that will return a list of open pull requests for Angular JS from github.

    Play with it

    http://jsbin.com/UfotanA/3/edit

    http://jsbin.com/UfotanA/3/edithttp://jsbin.com/UfotanA/3/edithttp://-/?-
  • 8/13/2019 Angular JS Ng Book Preview book

    9/13

    Promises 4

    1 Open Pull Requests for Angular JS

    2

    3

    4

    5 {{ pr.title }}

    6

    7

    If we have a service that returns a promise (covered in-depth in theserviceschapter), we can simply

    place the promise in the view and expect that Angular will resolve it for us:

    1 angular.module('myApp', [])

    2 .controller('DashboardCtrl', [

    3 '$scope', 'UserService',

    4 function($scope, UserService) {

    5 // UserService's getFriends() method

    6 // returns a promise

    7 $scope.friends = User.getFriends(123);

    8 }]);

    When the asynchronous call to getPullRequests returns, the $scope.pullRequests value will

    automaticallyupdate the view.

    How to create a promise

    In order to create a promise in Angular, well use the built-in $q service. The $q service provides a

    few methods in its deferred API.

    First, well need to inject the $q service into our object where we want to use it.

    1 angular.module('myApp', [])

    2 .factory('GithubService', ['$q', function($q) {

    3 // Now we have access to the $q library

    4 }]);

    To create a deferred object, well call the method defer():

    1 var deferred = $q.defer();

    The deferred object exposes three methods and the single promiseproperty that can be used in

    dealing with the promise.

    resolve(value)

    Theresolvefunction will resolve the deferred promise with the value.

    http://-/?-
  • 8/13/2019 Angular JS Ng Book Preview book

    10/13

    Promises 5

    1 deferred.resolve({name: "Ari", username: "@auser"});

    reject(reason)

    This willrejectthe deferred promise with a reason. This is equivalent to resolving a promise with arejection

    1 deferred.reject("Can't update user");

    2 // Equivalent to

    3 deferred.resolve($q.reject("Can't update user"));

    notify(value)

    This will respond with the status of a promises execution.

    TODO: Add notify example

    We can get access to the promise as a property on the deferred object:

    1 deferred.promise

    A full example of creating a function that responds with a promise might look similar to the following

    method on theGithubServiceas mentioned above.

    1 angular.module('myApp', [])

    2 .factory('GithubService', [

    3 '$q', '$http',

    4 function($q, $http) {5 var getPullRequests = function() {

    6 var deferred = $q.defer();

    7 // Get list of open angular js pull requests from github

    8 $http.get('https://api.github.com/repos/angular/angular.js/pulls')

    9 .success(function(data) {

    10 deferred.resolve(data);

    11 })

    12 .error(function(reason) {

    13 deferred.reject(reason);

    14 })

    15 return deferred.promise;

    16 }

    17

    18 return { // return factory object

    19 getPullRequests: getPullRequests

    20 };

    21 }]);

  • 8/13/2019 Angular JS Ng Book Preview book

    11/13

  • 8/13/2019 Angular JS Ng Book Preview book

    12/13

    Promises 7

    Angulars $q deferred objects are chainable in that even then returns a promise. As soon as the

    promise is resolved, the promise returned by thenis resolved or rejected.

    These promise chains are how Angular can support $https interceptors.

    The$q service is similar to the original Kris Kowals Q library:

    1. $q is integrated with the angular $rootScope model, so resolutions and rejections happen

    quickly inside of angular

    2. $q promises are integrated with angulars templating engine which means that any promises

    that are found in the views will be resolved/rejected in the view

    3. $q is tiny and doesnt contain the full functionality of the Q library

    chaining requests

    TODO:

    The$q library comes with several different useful methods.

    all(promises)

    If we have multiple promises that we want to combine into a single promise, then we can use the

    $q.all(promises)method to combine them all into a single promise. This method takes a singleargument:

    promises (array or object of promises)

    Promises as an array or hash of promises

    The all()method returns a single promise that will be resolved with an array or hash of values.

    Each value will correspond to the promises at the same index/key in the promises hash. Ifanyof

    the promises are resolved with a rejection, then the resulting promise will be rejected as well.

    defer()

    Thedefer()method creates a deferred object. It takes no parameters. It returns a new instance of a

    single deferred object.

  • 8/13/2019 Angular JS Ng Book Preview book

    13/13

    Promises 8

    reject(reason)

    This will create a promise that is resolved as rejected with a specific reason. This is specifically

    designed to give us access to forwarding rejection in a chain of promises. This is akin tothrowin

    javascript. In the same sense that we cancatchan exception in javascript and we can forward therejection, well need to rethrow the error. We can do this with $q.reject(reason).

    This method takes a single parameter:

    reason (constant, string, exception, object)

    The reasons for the rejection.

    Thisreject()method returns a promise that has already been resolved as rejected with the reason.

    when(value)

    The when()function wraps an object that might be a value then-able promise into a $q promise.

    This allows for us to deal with an object that may or may not be a promise.

    Thewhen()function takes a single parameter:

    value

    This is the value or a promise

    Thewhen()function returns a promise that can be then used like any other promise.