aurelia / aurelia/templating-resources
Iterate over Promises
- Dominant language
- TypeScript
- Stars
- 55
- Forks
- 55
- PR merge metrics
- No merged PRs in 30d
Description
**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:
```typescript
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
```typescript
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.
Contributor guide
Research direction
Start with Repeat and RepeatStrategyLocator, then inspect how existing repeat strategies handle collection changes. Use the proposed PromiseRepeatStrategy as the behavioral reference; done means a Promise-resolved collection can be iterated and updated, including item removal, without the workaround described.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100