angular with foreign (jQuery) promises

By eidias on (tags: angular, javascript, jQuery, categories: web)

When using angular turns out that it’s not as straightforward when it comes to foreign libraries.

I needed to use jQuery $.post instead of angulars $ method (to reduce the friction between angular and mvc regarding request token validation) and I came across unexpected (though understandable once you get to the core problem) behavior. Here’s the angular version:

   1: $, d)
   2:      .then(function() {
   3:                // do something with $scope
   4:            },
   5:            function() {
   6:                 // do something with $scope
   7:            })
   8:      .finally(function () { 
   9:                 // do something with $scope
  10:      });

and the jquery code fragment:

   1: $.post(...)
   2:     .done(function() {
   3:         // do something with $scope
   4:     })
   5:     .fail(function() {
   6:         // do something with $scope
   7:     })
   8:     .always(function() {
   9:         // do something with $scope
  10:     });

Not much of a difference besides function names…. but turns out the template sees the changes in the original (angular) version, but not the jquery version. Why? well… behind the scenes, angular promises call a very important (as it turns out) function:

   1: $scope.$apply()

This – as the name suggests – applies the changes on the $scope object so that the template can see them.

To resolve my primary issues I had two options.

  1. call $scope.$apply() manually in the .always() callback
  2. wrap the jquery promise in an angular promise using $q.when($.post(…))

I chose the latter one – who knows what else the angular promises do or what they will do in the future.