Last active
April 19, 2016 23:41
-
-
Save cvuorinen/b9e05cabf19f367ffc5f to your computer and use it in GitHub Desktop.
asyncFilter.js - {{ observableOrPromise | async }}
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular | |
.module('asyncFilter', []) | |
.filter('async', function() { | |
const values = {}; | |
const subscriptions = {}; | |
function async(input, scope) { | |
// Make sure we have an Observable or a Promise | |
if (!input || !(input.subscribe || input.then)) { | |
return input; | |
} | |
const inputId = objectId(input); | |
if (!(inputId in subscriptions)) { | |
const subscriptionStrategy = input.subscribe && input.subscribe.bind(input) | |
|| input.success && input.success.bind(input) // So it works with HttpPromise | |
|| input.then.bind(input); | |
subscriptions[inputId] = subscriptionStrategy(value => { | |
values[inputId] = value; | |
if (scope && scope.$applyAsync) { | |
scope.$applyAsync(); // Automatic safe apply, if scope provided | |
} | |
}); | |
} | |
return values[inputId] || undefined; | |
}; | |
// Need a way to tell the input objects apart from each other (so we only subscribe to them once) | |
let nextObjectID = 0; | |
function objectId(obj) { | |
if (!obj.hasOwnProperty('__asyncFilterObjectID__')) { | |
obj.__asyncFilterObjectID__ = ++nextObjectID; | |
} | |
return obj.__asyncFilterObjectID__; | |
} | |
// So that Angular does not cache the return value | |
async.$stateful = true; | |
return async; | |
}); |
If you return input
on line 10 then it is a noop for non async types.
Thanks @ggoodman for the comment, I'll change it.
This now has it's own repo at https://github.com/cvuorinen/angular1-async-filter and can be installed with npm or bower.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Works with Rx observables even without https://github.com/Reactive-Extensions/rx.angular.js
by providing scope as a param:
{{ observable | async:this }}
Here's a quick demo: http://jsbin.com/hubuva/edit?html,js,output