Before the promise is resolved, a directive is issued

I am having trouble getting my directive to provide its contents only after my promise is resolved. I thought then() should have done this, but it does not seem to work.

Here is my controller:

 // Generated by CoffeeScript 1.6.3 (function() { var sprangularControllers; sprangularControllers = angular.module('sprangularControllers', ['sprangularServices', 'ngRoute']); sprangularControllers.controller('productsController', [ '$scope', '$route', '$routeParams', 'Product', 'Taxonomy', function($scope, $route, $routeParams, Product, Taxonomy) { Taxonomy.taxonomies_with_meta().$promise.then(function(response) { return $scope.taxonomies = response.taxonomies; }); return Product.find($routeParams.id).$promise.then(function(response) { return $scope.currentProduct = response; }); } ]); }).call(this); 

My directive:

 // Generated by CoffeeScript 1.6.3 (function() { var sprangularDirectives; sprangularDirectives = angular.module('sprangularDirectives', []); sprangularDirectives.directive('productDirective', function() { return { scope: { product: '=' }, templateUrl: 'partials/product/_product.html', link: function(scope, el, attrs) { console.log(scope); console.log(scope.product); return el.text(scope.product.name); } }; }); }).call(this); 

The scope returns in order, and when I check it in dev tools, scope.product not undefined, however, I assume that since I check that the promise has been resolved?

console.log(scope.product) , however, returns undefined ..

+55
javascript angularjs angularjs-directive
Jan 17 '14 at 3:57 on
source share
4 answers

Since your value is asynchronously populated, you need to add a clock function that updates the related item.

  link: function(scope, el, attrs) { scope.$watch('product', function(newVal) { if(newVal) { el.text(scope.product.name);} }, true); } 

You can also move more complexity into a directory controller and use the link function to control only the DOM.

The third parameter true to $watch calls the deep clock, since you are binding this directive to the model.

Here are some links with good examples:
http://www.ng-newsletter.com/posts/directives.html
http://seanhess.imtqy.com/2013/10/14/angularjs-directive-design.html

+42
Jan 17 '14 at 4:16
source share

As stated in the official post about this problem (it quickly closes as β€œwill not be fixed because it will make the directives wait”), the workaround is the directive in ng-if :

 <div ng-if="myPromiseParam"> <my-directive param="myPromiseParam"> </div> 
+74
Feb 27 '15 at 13:27
source share

I know this is an older question, but I thought I'd try to help provide an updated answer.

When using a router, both ui-router and ngRouter have troubleshooting methods that will allow promises when changing the URL before going to this route and displaying objects on the page.

ngRouter Allow Tutorial
ui-router Allow documents

Another option, instead of using $watch is to use the $q corners promise library . More specifically, the $q.when() method. This takes on promises and meanings. IF this is a promise, it will work .then() when the promise is resolved. If this value, it assures him of the promise and immediately resolves it.

 link: function(scope, el, attrs){ $q.when(scope.product).then(function(product){ scope.product = product; el.text(scope.product.name); }); } 

Or where you cannot show anything, just with html.

 <product-directive product='object'> <!-- Will hide span until product.name exists --> <span ng-show='product.name'>{{ product.name }}</span> <!-- Will show default text until key exists --> {{ product.name || 'Nothing to see here' }} <!-- Will show nothing until key exists --> <span ng-bind='product.name'></span> </product-directive> 
+24
02 Oct '14 at 18:24
source share

use $ watch for your variable in your directive to get the updated value of your variable.

You can also use $ q to resolve the promise.

0
May 05 '17 at 6:14 a.m.
source share



All Articles