DC AngularJS Meetup

presented by 

Who are we?

Audax Health is a health software company that focuses on the health and wellness of individuals through our flagship product, Zensey.

Some features we use to engage with individuals:



Who am I?

Bryan Lin

  • Software Engineer at Audax Health
  • Work primarily in Scala...
  • But now am more focused on the AngularJS portion of our stack
  • Follow me @hooliganlin
  • Challenge me to any Halo game on Xbox Live: BK DERF1





Promises

My Promises to you


You will learn
var avoidCallbackHell = $q.deferred.promise
var chainingPromises = $q.deferred.promisevar createYourOwnPromises = $q.deferred.promise
$q.all([avoidCallbackHell, chainingPromisescreateYourOwnPromise]) .done(function() { // celebrate })

JavaScript and Async

  • Asynchronous functionality is achieved through callbacks
  •  var orderCompleted = false;
     placeOrder(order, function(result) {
       orderCompleted = result.success;
       alert('I got my order!', result);           
     }); 
     
     //do some other things while we are placing an order
     doingSomethingElse();

  • Callbacks are a response to an event that has finished, but it does not return a value.

But wait...

What if I wanted to read a value which the callback function was modifying??
var orderCompleted = false; placeOrder(order, function(result) {
   orderCompleted = result.success;          
});
//NOO!!!!! orderCompleted is not guaranteed that the order was completed!!shipOrder(order, orderCompleted);

So to "guarantee" the value has been updated...


placeOrder(order, function(results) {
  //Insert the function to ship the order in the callback... shipOrder(order, results.completed); });

But to add more complexity...

    placeOrder(order, function(result) {
            authorizeCC(creditCard, function(validCC) {
                validateShippingAddr(address, function(validAddress) {
                    shipProduct(order, function(result) {
                       //order shipped!! right???
                       //result.success?? validCC???
                    });
                });
            });
        });


CALLBACK HELL!!!!

Enter in...




Promises

Not this promise:



But this promise:

(note this is part of the Q library by Kowal)

var creditCardValidated = placeOrder(order).then(authorizeCC);var shippingValidated = creditCardValidated.then(validateShipping)
Q.all([creditCardValidated, shippingValidated]).done(shipProduct)


Delivery of promise #1: 

Avoiding callback hell

What's a Promise?

  • a container that holds or will hold a value
  • a time-independent proxy for a remote/external object
  • an instance of a class that has utility methods like .then()
  • a 'frozen event' you can learn status of at any time
  • It's a first-class object so you can: 
    • Pass it
    • Reference it
    • Chain it


Reference: http://christianlilley.wordpress.com/2013/09/19/promises-promises-mastering-async-io-in-javascript-with-the-promise-pattern/

Why Promises?

  • Easy to read when dealing with async
  • You will always be guaranteed a return value/state (fulfilled, unfulfilled, failed)
    • You know that value returned within the promise is the value that you expect (even if it's a failure).
  • Flexible 
    • You can chain multiple promises and do something after they have all been fulfilled
 var promise = Q.all([promise1, promise2]).then(finalPromise)

Angular's promises

//Using the promisefuncThatReturnsAPromise().then(function(success) { console.log(success);}, function(error) {  console.log(error)};
//Creating the promise var promise = function() {   var deferred = $q.defer();   if (fail)      deferred.reject('oh no!!!');   else       deferred.resolve('happy!');   return deferred.promise;}

$q

  • AngularJS $q is inspired by Kris Kowal's Q.
    • Doesn't contain all the features of Q, but the important functionalities
    • Integrated with the $rootScope (avoid browser repaint when the model updates)
  •  Contains two API:
    • Promise API 
    • Deferred API

Promise API

  • .then()
    • The action to be executed upon a fulfilled promise
    • Actions are callbacks that are resolvedrejected, and notified
    • Returns a new promise
 var ccPromise = CreditCardService.validateCC(cc).then(   function(result) {     //resolved     console.log('You have a valid credit card', result);   },   function(error) {     //rejection     console.log('Dude, something is not right with your card', error);   },   function(msg) {      //notify callback      console.log('I have been notified', msg);   });

Promise API

  • Then() (cont.)
    • Because it returns a promise, you can chain them!
 var shippingPromise = CreditCardService.validateCC(cc)                        .then(validateShipping)                        .then(calculateTotalPrice)                        .then(shipOrder)

It just makes sense!


Delivery of promise #2: 

Chaining promises

Promise API

  • catch()
    • shorthand for a promise with only a rejection 
    •  promise.then(null, rejectionCallback)
  • finally()
    • Think of it as the finally block of a try-catch block. It will always be executed at the end of a statement regardless of a fullfilment or rejection

Defer API

   Purposes of the deferred:
  1. Creates a promise
    var deferred = $q.defer(); // promise created internall
  2. You return the promise, and fulfill it later.

    return deferred.promise;
  3. Signals the status of the promise (resolve, reject, notify)
    deferred.resolve('successful callback!');
    deferred.reject('go home fool, you just got rejected!');
    deferred.notify('I just got an alert!');

Defer API

Example above expanded
 var doSomethingAsync = function() {   var deferred = $q.defer();   $timeout(function() {     deferred.resolve('Done after 500 milliseconds');   }, 500);
return deferred.promise; }
doSomethingAsync().then(function(resp) {   //the message appears after ~500 milliseconds console.log(resp); });

Recap on Promises and Deferred

According to Christian Lilley's metaphor: "A Promise is a mailbox"
  • It contains the message you want
  • You can pick it up and bring it to whatever context it needs to be in

 Reference: http://www.slideshare.net/xmlilley/postal-for-promises-20-min

And the deferred is the mailman


  • Assigns you a new mailbox (creating a promise)
  • Puts the mail into mailbox (resolve the promise)
  • Raises the flag on the box (set the state of the promise)

 Reference: http://www.slideshare.net/xmlilley/postal-for-promises-20-min

AngularJS is filled with promises

  • $http
  • $route
  • $timeout
  • $resource




Let's create a promise!








Delivery of promise #3: 

Creating your own promises


http://bit.ly/1j2a2s4

Before

$q.defer().promise.resolve(nextSpeaker()) 


Questions?

Made with Slides.com