rwxr--r--
/dev/blog

Bez Hermoso, Software Engineer @ Square

The bluebird library doesn’t quite work with Angular out-of-the-box. You’ll have to configure bluebird to execute resolution/rejection functions within Angular’s digest loop. I also learned that even if you have that in place, ui-router’s Resolve functionality still wouldn’t work with bluebird promises. You’ll have to do something extra for that, too:

If you need bluebird’s superior Promise objects within Angular and with ui-router, you’ll have to configure it like this:

var app = angular.module('main');

app.run(function ($rootScope, $q) {
    
  // This ensures that resolutions/rejections are ran
  // within Angular's digest loop:
  Promise.setScheduler(function (fn) {
    $rootScope.$evalAsync(fn);
  });

  // Wrap the promise's resolution/rejection within a $q.defer promise.
  Promise.prototype.qDeferred = function () {
    var deferred = $q.defer();
    this.then(deferred.resolve, deferred.reject);
    return deferred.promise;
  };
});

With that in place, we can now easily produce a Promise object of the proper type whenever necessary:

$stateProvider.state('stuff', {
  resolve: {
    collection: function () {
      return Promise.all([ ... ]).qDeferred();
    }
  }
});

// This will work now as well:

Promise.map(urls, function (url) {
  return $http.get(url);
}).then(function (results) {
  $scope.results = results;
});
comments powered by Disqus