Directive is being rendered before promise is resolved
Solution 1:
As stated in an official thread about this issue (quickly closed as "won't fix because it would make directives wait"), a workaround is to wrap your directive in a ng-if
:
<div ng-if="myPromiseParam">
<my-directive param="myPromiseParam">
</div>
Solution 2:
Because your value is asynchronously populated, you'll want to add a watch function that updates your bound element.
link: function(scope, el, attrs) {
scope.$watch('product', function(newVal) {
if(newVal) { el.text(scope.product.name);}
}, true);
}
You could also move a lot of complexity into a directive controller and use the link function for manipulating the DOM only.
The true
third parameter to $watch
causes a deep watch, since you're binding this directive to a model.
Here are a couple of links with good examples:
http://www.ng-newsletter.com/posts/directives.html
http://seanhess.github.io/2013/10/14/angularjs-directive-design.html
Solution 3:
I know this is an older question, but thought I would try my hand at providing an updated answer.
When using a router, both ui-router and ngRouter have resolve methods that will resolve promises on url changes before switching to that route and rendering things on the page.
ngRouter Resolve tutorial
ui-router Resolve docs
Another option, instead of using $watch
is to use angulars $q
promise library.
More specifically, the $q.when()
method. This takes promises and values. IF it's a promise it will fire a .then()
when the promise resolves. If its a value, it wraps it in a 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 there a couple way you can not 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>