Handling Promises with $q in Angular JS

Old way of async operations

 
function getCurrentUser(callback)
$http.get("/api/users/me")
.success(function(user){
callback(user);
});

//Let assume if you have two functions as below
getCurrentUser(function(user){
//function one
//some task with user
});
getPermissions(function(permission){
//function two
//some task with permissions
});

//If you need this both results simultaneously (Serialized)
//you can use as below as for old method
getCurrentUser(function(user){
getPermissions(function(permission){
//do what you want with users and permissions
//But it contains following issues
//[1] Not Parallelizable
//[2] Not Composable
//[3] Not Dynamic (have to define the structure at runtime)
});
});

Better way if you go with Angular JS is service implementation. Its as below;

 
//Then better way is $q
//Service implemenation as below
function getCurrentUser(){
//define deferred
//this is one time use object
var deferred = $q.defer();
//resolve object into deferred
$http.get("/api/users/me")
.success(function(user){
deferred.resolve(user);
});
//return promise
return deferred.promise;
}
//Calling it, some what different other than old method
getCurrentUser()
.then(function(user){
//do tasks with user
//Async call
})

//How to make two functions parallelizable
$q.all([getCurrentUser(),getPermissions()])
.then(function(responses){
//returns of user
var user=responses[0];
//returns of permissions
var permissions=responses[1];

//This will call defined methods parallel
//Wait for both methods, without moving to next in program flow
//$q.all doing this magic for us
});

//Following have been separated because to enforce separation of notifier and receiver

deferred.resolve() //notifier (mostly in service side)
promise.then() //receiver (mostly in controller side)

// Some more functions we getting as below
// [1] Send errors like below by notifier
deferred.reject()
// [2] Send progress updates
deferred.notify(...)

//
// Receiver implementation for above as below
//
promise.then(function(){
// to do when Success
},function(){
//[1]
//to do when failure
},function(){
//[2]
//progress (i.e called 0 or more times)
});

//_____________________________________________________________________________________
//
$q.when();
//Can be used for client side caching
myApp.factory("Movies",function($q,$http){

var chachedMovies//will store cached movies
,p//promise that returns when same request called while helper function is executing;

return{
getMovies:function(){
//***
//return cahedMovies else call helper to get data
//***
return $q.when(cachedMovies || p || helper());
}
};

//helper function
function helper(){
var deffered=$q.deffer();
//return the loaded values if this function called while http GET is processing
p = deffred.promise;
//
$http.get("/movies").success(function(movies){
chachedMovies=movies;
deffered.resolve(movies);
});
return deferred.promise;
}
});

https://docs.angularjs.org/api/ng/service/$q

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s