Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Sunday, October 20, 2013

Creating a Promise from a Node.js style function

Recently I had a situation where I needed to process a web request, write data into three databases and then send a response to the client i.e. success if all three writes succeeded and a failure if even one of them failed.

I wanted keep my code simple and not have to track state across three asynchronous calls. Promises seemed like the natural answer, however it turned out that the MongooseJS API do not return promises (currently).

Fortunately I discovered that the excellent Q library also supports denodefiying calls thus making a standard nodejs API call with call-backs fit into the Promise pattern.

Here’s an example

           /* req is the request passed in by express*/
            var objectA = new ModelA(req.body.objectA);  // instantiate objects from the requests 
            var objectB = new ModelB(req.body.objectB);
             var objectC = new ModelC(req.body.objectC);
           
               // create promise returning functions and bind the methods to the objects
            var saveObjectA = Q.nbind(objectA.save, object;
            var saveObjectB = Q.nbind(objectB.save, objectB);
            var saveObjectC = Q.nbind(objectC.save, objectC);

               Q.all ( [saveObjectA(), saveObjectB(), saveObjectC() ] )
                .then(function (arr) {
                 // The two callbacks for then deal with success and failure respectively
                // success returns an array of arrays. Each internal array lists the item written
     // and number of items written. This is essentially an array of parameters passed to the
    // callback in the original function i.e. before denodeifying

                   res.send(200, {objectAid: objectA.id });
            }, function (err){
                console.error(err);
                 res.send(500); // send a server error

            });

and that's it 

Monday, July 29, 2013

Promises in AngularJS

Today I was working on the front end and discovered that I had a race condition while fetching data from two URLs.
I was doing something like this
$http.get(firstUrl).success(function(data){
// initialize $scope.data1 and some other work
}
$http.get(secondUrl).success(function(data){
// initialize $scope.data2 and some other work
}
scope.doSomething($scope.data1, $scope.data2);
The results from doSomething were flaky and I realized, I’d been counting on both http.get’s returning in the same order when in case that was not always the case.
To cut a long story short, I discovered the solution was to use AngularJS promises to ensure that both the http operations were completed before the doSomething() function was called. There’s a lot of stuff on the subject on Stack Overflow and other places especially on more complex scenarios but I couldn’t find a nice concise snippet for my very simple case. So here goes
var myCtrl = function ($scope,$http,$window,$q) {
$scope.firstDataPromise = $http({
method:’GET’
,url:$scope.firstDataRecordUrl
});
$scope.secondDataPromise = $http({
method:’GET’
,url:$scope.secondDataRecordUrl
});
$q.all([
$scope.firstDataPromise
,$scope.secondDataPromise
])
.then(function(data){
//data is an array of objects. The first element in the array is result
// of executing the first promise and the second …
$scope.doSomething(data);
});
}