Skip to content

Instantly share code, notes, and snippets.

@cvuorinen
Last active April 19, 2016 23:41
Show Gist options
  • Save cvuorinen/b9e05cabf19f367ffc5f to your computer and use it in GitHub Desktop.
Save cvuorinen/b9e05cabf19f367ffc5f to your computer and use it in GitHub Desktop.
asyncFilter.js - {{ observableOrPromise | async }}
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;
});
@ggoodman
Copy link

If you return input on line 10 then it is a noop for non async types.

@cvuorinen
Copy link
Author

Thanks @ggoodman for the comment, I'll change it.

@cvuorinen
Copy link
Author

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