Enhancing Angular Promises: Returning new promise of field or method called from original promise’s result

posted in: AngularJS | 6

The title is kind of confusing as it’s really hard for me to explain what I want to enhance on Angular promises without actually showing.

So, what’s the idea? You have a function that returns a promise for an object A. Let’s assume that that object is an Array for our example. And what you want is actually the length fo that array. So, given the promise, instead of setting the callback for the value and then assigning that value to some variable and doing something, what we’re going to do is to apply a transformation. We’re going to transform this Promise of an Array to a Promise of a Number (the length). Normally, for this you actually set a function called map which transforms the A to B (once A is received) and therefore returns a Promise of B. Scala for example has map and flatMap for promises.

I implemented this without functions, using names of the fields or of the function. So, let’s see some code to finally understand this.

So, what’s the usage of this? Angular already knows how to work with promises and how to resolve them when working with views. What this means is that if in our template we put {{lengthPromise}}, once the promise is resolved (value is returned), it will be shown in the HTML. Before, nothing will be shown. That’s thanks to using $q from Angular.

So, let’s see the implementation.

I’ve implemented it in Restangular but I’m thinking in creating an Angular module for this. Do you think it’d be useful?

That’s all folks

Share!Share on FacebookTweet about this on TwitterShare on RedditShare on Google+Share on LinkedInBuffer this pageEmail this to someoneFlattr the author
  • http://domenicdenicola.com/ Domenic Denicola

    This is pretty nice. I’d encourage you to call it `invoke` instead of `call`; `call` would normally accept a `thisArg` parameter and call a promised function, instead of calling a method on a promised object. Plus, that way you match the Q library which Angular is based on :).

    See https://github.com/kriskowal/q/wiki/API-Reference#promise-for-object-methods for some more fun methods that Q has along these lines.

  • madrona_ecotrust

    Hi Gonto, restangular is amazing!

    Would there any way to use an enhanced promise to “get” the first item a field that is actually an array?

    Thanks!

    • Martin Gontovnikas

      I think you can do it like arrayPromise.get(’0′) and that will return the promise of the first element. I’m pretty sure that will work.

      But if you want the first item, why not just using then and “resolving” the promise?

  • finestglasses j.

    At the internet vendors severe pharmaceutical drug cups, you’ll get these Designer Glasses from means less expensive costs than others at the actual shops.

  • Alain

    I don’t like how calling `enhancedPromise.get(‘subProperty’)` here invokes / resolves the ‘wrapped’ promise before `then` even gets called. I feel like proper promises should wait until `then(…)` is called before resolving. Is there a way you can implement the above such that `this.then(…)` is only called once someone attempts to resolve your new `deferred`?

    • Martin Gontovnikas

      Hey,

      The promise does wait until it gets resolved.

      Having:

      newPromise = enhancedPromise.get(‘subProp1′);

      newPromise will be resolved ONLY when enhancedPromise is resolved. However, newPromise is a promise of subProp1.

      Does that answer your question?