Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterate over Promises #288

Open
Joxeur opened this issue Jul 8, 2017 · 0 comments
Open

Iterate over Promises #288

Joxeur opened this issue Jul 8, 2017 · 0 comments
Labels

Comments

@Joxeur
Copy link

Joxeur commented Jul 8, 2017

I'm submitting a feature request

  • Library Version:
    1.4.0

Current behavior:

Currently one can't really easily iterate over the result of a Promise.

I am in a situation where I an array of Files and I need to extract their dimensions to be able to use http://photoswipe.com. Extracting those information is however an asynchronous task as one need to have the image loaded to get its dimension.

I wrote a ValueConverter that takes an array of Files and return a Promise containing the same list of Files with metadata. But I then needed to iterate over this Promise. It took me some time before I figured out what was the best way to do so.

I first tried with an asynchronous BindingBehavior. It worked when I was assigning a new array, but not when I was removing an item from the array. I could then get it to work by removing the item from a clone of my array and reassigning it to the original, but I didn't find it very elegant.

I then read about these RepeatStrategies and thought it would be a nice way to solve my problem. I then wrote a strategy for Promises that is just a wrapper to other already existing strategies:

import { Repeat, RepeatStrategyLocator } from 'aurelia-templating-resources';

export class PromiseRepeatStrategy {

  constructor(private repeatStrategyLocator: RepeatStrategyLocator){}

  instanceChanged(repeat: Repeat, promise: any): void {
    promise.then((items) => {
      const strategy = this.repeatStrategyLocator.getStrategy(items);
      if(!strategy){
        throw new Error('Value for \'' + items + '\' is non-repeatable');
      }
      strategy.instanceChanged(repeat, items);
    });
  }
  instanceMutated(repeat: Repeat, promise: any, changes: any): void {
    promise.then((items) => {
      const strategy = this.repeatStrategyLocator.getStrategy(items);
      if(!strategy){
        throw new Error('Value for \'' + items + '\' is non-repeatable');
      }
      strategy.instanceMutated(repeat, items, changes);
    });
  }
  getCollectionObserver(observerLocator: any, items: any): any {}
}

Then its registration

repeatStrategyLocator.addStrategy(items => items && typeof items.then === 'function', new PromiseRepeatStrategy(repeatStrategyLocator));

I thought it could help one facing the same problem and would be nice to have it directly native in the library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants