Angular JS: how to get attached to promises

I am trying to connect a promise with a presentation. I don’t know if you can do it directly, but this is what I am trying to do. Any ideas what I'm doing wrong?

Note: the source is a bit contrived with a timeout and uses static data, but this makes it easier to diagnose the code.

EDIT: JSFiddle Page: http://jsfiddle.net/YQwaf/27/

EDIT: SOLUTION: It turns out that it can directly bind promises. I had two problems with my source code:

  • Using setTimeout () instead of angular $ timeout was a problem. angular does not know that it needs to update the user interface when the timeout starts (you can solve this with $ scope. $ apply inside setTimeout or just use $ timeout)
  • Binding to the function that returned the promise was a problem. If he is called a second time, this is another promise. It is best to set the scope variable and create a new promise if necessary. (In my case, it caused $ scope. $ Watch in the country code)

HTML:

<div ng:controller="addressValidationController"> Region Code <select ng:model="regionCode" ng:options="r.code as r.name for r in getRegions()"/> Country Code<select ng:model="countryCode"><option value="US">United States</option><option value="CA">Canada</option></select> </div> 

JS:

 function addressValidationController($scope, $q) { var regions = { US: [{code: 'WI',name: 'Wisconsin'}, {code: 'MN',name: 'Minnesota'}], CA: [{code: 'ON',name: 'Ontario'}] }; $scope.getRegions = function () { var deferred = $q.defer(); setTimeout(function () { var countryRegions = regions[$scope.countryCode]; console.log(countryRegions); if(countryRegions === undefined) { deferred.resolve([]); } else { deferred.resolve(countryRegions); } }, 1000); return deferred.promise; }; } 
+60
angularjs promise
Oct 23 '12 at 14:45
source share
3 answers

WARNING : this answer was accurate when it was written, but since 1.2 the Angular template engine does not handle transparent promises! - @Malvolio

Yes, the mechanism of templates (and expressions) handles transparently, but I would assign a promise to the scope property in the controller and each time I would not call a function that returns a new promise (I think this is your problem, lost because a new promise is returned every time).

JSFiddle: http://jsfiddle.net/YQwaf/36/

HTML:

 <div ng:controller="addressValidationController"> Region Code <select ng:model="regionCode" ng:options="r.code as r.name for r in regions"/> Country Code<select ng:model="countryCode"><option value="US">United States</option><option value="CA">Canada</option></select> </div> 

JS:

 function addressValidationController($scope, $q, $timeout) { var regions = { US: [{ code: 'WI', name: 'Wisconsin'}, { code: 'MN', name: 'Minnesota'}], CA: [{ code: 'ON', name: 'Ontario'}] }; function getRegions(countryCode) { console.log('getRegions: ' + countryCode); var deferred = $q.defer(); $timeout(function() { var countryRegions = regions[countryCode]; if (countryRegions === undefined) { console.log('resolve empty'); deferred.resolve([]); } else { console.log('resolve'); deferred.resolve(countryRegions); } }, 1000); return deferred.promise; }; $scope.regions = []; // Manage country changes: $scope.$watch('countryCode', function(countryCode) { if (angular.isDefined(countryCode)) { $scope.regions = getRegions(countryCode); } else { $scope.regions = []; } }); }​ 
+28
Oct 23
source share

Starting with Angular 1.2, you can no longer use promises in templates .
Instead, you need to put the result in $scope inside then , as usual, there would be no magic.

As a temporary workaround for getting old behavior, you can call

 $parseProvider.unwrapPromises(true) 

but this function will be removed later, so do not depend on it.

+71
Jan 24 '14 at
source share

From Angular 1.3 - $parseProvider.unwrapPromises(true) will no longer work .

Instead, you should deploy promises directly:

 myApiMethod().then(function(value){ $scope.item = value; }); 

Note that defusing promises will still work with ngResource, as usual.

+25
Sep 14 '14 at 19:11
source share



All Articles