Skip to content

Instantly share code, notes, and snippets.

@ef4
Last active December 1, 2017 19:20
Show Gist options
  • Save ef4/bf2c9900dded40eaabb83dd4430a1716 to your computer and use it in GitHub Desktop.
Save ef4/bf2c9900dded40eaabb83dd4430a1716 to your computer and use it in GitHub Desktop.
import { liveQuery } from '@cardstack/live-models';
import Component from '@ember/component';
export default Component.extend({
// liveQuery is implemented as a computed property. It doesn't do
// anything until somebody tries to get `comments`.
//
// When it does run, it does a store.query(...), while also
// subscribing to a socket-based change feed that will casue it to
// keep the models up-to-date as they change or as the set itself
// changes.
//
// The subscription is cleaned up automatically when this component
// is destroyed.
//
// The value of the actual CP starts out as an empty array and when
// we get the first query results we pushObjects them into it, so
// that anybody depending on `comments.[]` will recompute the normal
// way.
//
// We would also want to add some extra properties to the array for
// people who want to wait for it to actually become ready first,
// like `isPending`, `isReady`.
//
// In this example `postId` is a dependent key, just like a normal
// computed property would use. Meaning if that changes, we will
// automatically rebuild the live query based on the new value.
comments: liveQuery('postId', function(postId) {
// The return value from this function is basically the input to
// store.query(), except I'm combining all the positional args
// into a single pojo.
return { type: 'comments', filter: { post_id: postId } };
}),
// A shorthand for liveQueries that don't have any dependent keys
// could be:
// comments: liveQuery({ type: 'comments' })
});
export function liveQuery(...deps, fn) {
let query;
return computed(...deps, function(propName) {
if (query) {
// we have already run before, we're recomputing due to a dependent key change
query.cleanup();
} else {
// first time
this.on('willDestroyElement', () => query.cleanup());
}
let inputs = fn(...deps.map(d => this.get(d)));
query = new LiveQuery(inputs, getOwner(this));
return query;
})
}
class LiveQuery extends Ember.Array {
...
}
{{#if comments.isPending}}
{{loading-spinner}}
{{else}}
{{#each comments as |comment|}}
{{cardstack-content content=comment format="list-entry" }}
{{/each}}
{{/if}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment