Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass promises as directive attributes in Angular

I'd like to set up a promise and then throw it into a directive (using the databinding '=' attribute type) and do the then magic within the directive, but passing the promise as an attribute seems to result in the promise being resolved as undefined, so the then (and any other promise functionality) is unavailable.

like image 418
Cebjyre Avatar asked Jun 18 '13 02:06

Cebjyre


People also ask

How do you write a promise in Angular 8?

How To Create Promises in Angular? To create a promise in Angular we just need to use 'new Promise(function)' syntax. The promise constructor takes function as a parameter and that inner function takes resolve and reject as a params.

What are promises Angular 9?

Because they are promises you need to respect their resolve time, it means to wait until they are completed and that means you can't call them as a normal function when you rely on their result. Also because it's an angular app try to convert them to rxjs stream via from function.

Which directive definition option is used to replace the current element if true?

As the documentation states, 'replace' determines whether the current element is replaced by the directive. The other option is whether it is just added to as a child basically.


2 Answers

I suspect this is due to this specific tweak:

$q promises are recognized by the templating engine in angular, which means that in templates you can treat promises attached to a scope as if they were the resulting values - angular $q docs

and this essentially results in the promise being converted within the template to the $$v value that the promise uses to store the resulting value, and at the linking stage this is likely to still be undefined - the converted value (ie undefined), not the promise itself is then passed into the directive.

The workaround is not to use the promise itself as the attribute passed into the directive, but to make it part of a parent object: the parent object won't have $q/template engine magic run, and so you'll be able to drill down into the promise from the parent and access then functionality from there.

See http://jsfiddle.net/cebjyre/95sjT/ for an example - uncommenting line 32 will cause a failure due to the top level promise no longer actually being a promise at that point, whereas the second level promise on line 17 works fine

like image 69
Cebjyre Avatar answered Oct 12 '22 02:10

Cebjyre


Thanks. I have added this to Angular docs.

http://docs.angularjs.org/api/#comment-984109158

To achieve this wrap your promise in the parent: $scope.myDirectiveAtrribute = {promise: deferred.promise} and then in the directive access the promise

$scope.myDirectiveAtrribute.promise.then(function(){});

like image 31
Ronan Rafferty Avatar answered Oct 12 '22 03:10

Ronan Rafferty