Angular promises and http

JavaScript Async

The problem

The Solution

function loadPage{
    $('#spinner').show();
    setupPage();
    $('#spinner').hide();
}
function loadPage{
    $('#spinner').show();
    
    setTimeOut(function(){
        setupPage();
        $('#spinner').hide();
    }, 0);
}

The DOM manipulation tasks are not executed until this task's stack clears. The spinner isn't shown until setUp is completed.

Add a task to execute when this stack clears.

JavaScript needs Async

  • JavaScript is single threaded (*mostly);
  • Long running process will kill user experience: 
    • UI elements will be unresponsive;
    • animations will pause
  • Long running task will timeout;

Most I/O APIs are async:

  • Ajax
  • Web Workers, WebSQL, IndexedDb;
  • Timers: setTimeout()setInterval();
  • Other APIs
  • The Event Loop is a queue of callback functions;
  • When an async function executes, the callback function is pushed into the queue;
  • The JavaScript engine doesn't start processing the event loop until all the code was executed;
  • The event loop is a first-in-first-out (FIFO) queue;

How to Write Async JavaScript

Naive Approach

Callbacks:

function doSomethingAsync(callBack){
    setTimeout(function(){
        //.....
        callBack();
    }, 200);
}

doSomethingAsync(function(){
    //will be called after 200ms
});

Callbacks Hell:

function doSomethingAsync(callBack){
    //...
}

doSomethingAsync(function(result){
    //...
    doSomethingAsync(function(result){
        //...
        doSomethingAsync(function(result){
            //...
        });
    });
});

Better Approach

function doSomethingAsync(callBack){
    //...
}

var promise = doSomethingAsync();

promise
    .then(function(result){    
        //...
        if(!ok) throw new Error();
        
        return doSomethingAsync2();
    })
    .then(function(result2){
        //...
    }, function(reason){
        // Handle the error
    });

Promises

What is a promise?

  • A promise is always async;
  • A promise represents a task that will finish in the future;
  • A promise expose a function (then) :
    • then returns a new promise;
    • allows for the attachment of handlers that will be executed based on state;
    • handlers are guaranteed to execute in order attached;
  • Promises become resolved by a value;
  • Promises get rejected by exceptions;

Promise states

Promises in Angular

$q service

Angular Promises

Angular uses promises for everything that is async:

  • $timeout;
  • $http;
  • $routeProvider.when;
  • much more.

Deferred API

//Service
function doSmth(){
    defered = $q.defer();

    asyncOperation(function(error, data){
        if (!error) defered.resolve(data);
        else defered.reject(error);
    });

    return defered.promise;
}

//Controller
doSmth().then(function(value){
    console.log(value);
}, function(err){
    console.error(err);
});

console.log("The value will be shown after this.");

Result of $q.defer()

Angular promise API

Result of deffered.promise

doSmth()
    .then(function(value){
        return value + 10;
    }, 
    errorFn, 
    notifyFn)

    .then(function(value){
        return $q.reject(new Error());
    })

    .catch(function(err){
        console.err(err);
    })

    .finally(callbackFn);

Angular Server-side communication

$http service

$http

  • core Angular service for communication with remote HTTP servers;
  • can communicate via the browser's XMLHttpRequest ​or via JSONP;
  • works hand in hand with $q service.

$http

 The $http service is a function which takes a single argument — a configuration object — that is used to generate an HTTP request and returns a promise with two $http specific methods: success and error.

$http({method: 'GET', url: '/someUrl'})
    .success(function(data, status, headers, config) {
      // this callback will be called asynchronously
      // when the response is available
    })
    .error(function(data, status, headers, config) {
      // called asynchronously if an error occurs
      // or server returns response with an error status.
    });

*Since the returned value is a promise, you can also use then() for registering callbacks.

$http shortcut methods

$http.get
$http.head
$http.post
$http.put
$http.delete
$http.jsonp
$http.patch

$http config object

Demo

Going "Real Time"

Angular promises and http

By Alexe Bogdan

Angular promises and http

JavaScript Async, Angular $q service and $http service

  • 1,559