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

LiveQuery lifetimes #311

Open
ef4 opened this issue Oct 7, 2020 · 4 comments
Open

LiveQuery lifetimes #311

ef4 opened this issue Oct 7, 2020 · 4 comments

Comments

@ef4
Copy link
Contributor

ef4 commented Oct 7, 2020

I see that LiveQuery uses the ember-destroyable-polyfill, and that all queries get destroyed when the cache itself gets destroyed.

But it seems likely that many live queries have a lifetime shorter than that, like being associated with a component. In my own experiments, I have a utility like this:

// app/lib/query.js
import { associateDestroyableChild } from '@ember/destroyable';
import { getOwner } from '@ember/application';

export function liveQuery(parent, query) {
  let records = getOwner(parent).lookup('service:store').cache.liveQuery(query);
  associateDestroyableChild(parent, records);
  return records;
}

That I use like this:

// app/components/my-component.js
import { liveQuery } from '../lib/query';

export default class extends Component {
  observations = liveQuery(this, (qb) =>
    qb.findRecords('observation').sort('-time')
  );
}

This ensures that the live query is destroyed whenever its parent component is destroyed.

Is there a better built-in solution? Should something like this utility be added to ember-orbit?

@dgeb
Copy link
Member

dgeb commented Oct 8, 2020

@ef4 I definitely see where you're coming from and would be glad to integrate a similar solution into ember-orbit. I'd prefer to not hard-link the store service within a general solution, since there's often more than one store at any given time in an orbit application, especially when using forks.

We should consider incorporating the ability to create a dependent relationship in LiveQuery itself. I'm having trouble coming up with the perfect method name - perhaps associateParent(parent) or dependentUpon(parent)? Regardless, this method could return this (the LiveQuery instance) to make it seamless to use. For instance:

// app/components/my-component.js
import { liveQuery } from '../lib/query';

export default class extends Component {
  @service store;

  observations = this.store.cache.liveQuery((qb) =>
    qb.findRecords('observation').sort('-time')
  ).associateParent(this);
}

@tchak
Copy link
Member

tchak commented Oct 16, 2020

My plan is to wait for invokeHelper and then implement some form of @usable pattern. But maybe we can have utility like what you suggesting for now.

@tchak
Copy link
Member

tchak commented Oct 16, 2020

The problem I see with suggested utilities is that there no way with them to bind live query to some of component tracked properties. Another advantage of invokeHelper is that result could be of any shape unlike the current custom iterable which works only with collections.

@ef4
Copy link
Contributor Author

ef4 commented Oct 20, 2020

You can implement this with tracked property support already, without any private API. Here's a demo that does that for a remoteData property. It will correctly recompute if this.args.id changes:

https://github.com/ef4/jan2020-meetup-example/blob/ea56f69ddcb2d51638ef6ce04a4d87e6485a4cf0/app/components/use-decorator-station.js

Now that the destroyables API is shipping in the current Ember release (and polyfilled), you could combine destroyable plus this pattern to do all of this in an addon.

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

No branches or pull requests

3 participants