Skip to content

Instantly share code, notes, and snippets.

@jasonmit
Last active March 7, 2019 21:46
Show Gist options
  • Save jasonmit/b97b68ea852d7cc16811a09b0270dc05 to your computer and use it in GitHub Desktop.
Save jasonmit/b97b68ea852d7cc16811a09b0270dc05 to your computer and use it in GitHub Desktop.
Controlling flow of subscription backed model
import { run } from '@ember/runloop';
import Component from '@ember/component';
import { action } from '@ember-decorators/object';
import { task } from 'ember-concurrency-decorators';
import { argument } from '@ember-decorators/argument';
import { inject as service } from '@ember-decorators/service';
import { layout, tagName } from '@ember-decorators/component';
import { readOnly } from '@ember-decorators/object/computed';
import { shapeOf } from '@ember-decorators/argument/types';
import query from 'os-workflows/queries/fetch-tracker';
import template from './template';
@tagName('')
@layout(template)
export default class TrackerPageContainer extends Component {
@service apollo;
@argument(shapeOf({ projectId: 'string' }))
variables;
@readOnly('setupQuery.isRunning')
isLoading;
_variables = null;
_observable = null;
_pending = null;
_locked = false;
didReceiveAttrs() {
super.didReceiveAttrs(...arguments);
const next = this.variables;
const previous = this._variables;
if (previous !== next) {
if (previous) {
this._cleanup();
}
this.setupQuery.perform(next);
this._variables = next;
}
}
willDestroy() {
super.willDestroy();
this._cleanup();
}
@task
setupQuery = function*(variables) {
this._observable = this.apollo.watchQuery({ query, variables });
this._subscription = this._observable.subscription({
next: this._onSubscriptionNotice
});
yield this._observable.result();
};
@action
_onSubscriptionNotice(model) {
if (this._locked) {
this._pending = model;
return;
}
this._onModelChanged(model);
}
@action
refetch() {
this._observable.refetch();
}
@action
sync() {
if (this._locked && this._pending) {
this._onModelChanged(this._pending);
this._pending = null;
}
this._locked = false;
}
@action
pause() {
this._locked = true;
}
_cleanup() {
this._subscription.unsubscribe();
this._observable.tearDownQuery();
this._subscription = null;
this._observable = null;
}
_onModelChanged(model) {
run.join(this, 'set', 'model', model);
}
}
<TrackerProvider @variables={{hash (osProjectId=this.projectId)}} as |model provider|>
{{#if provider.isLoading}}
<TrackerLoading />
{{else}}
<TrackerPage @model={{model}} @syncTracker={{provider.sync}} @pauseTracker={{provider.pause}} as |T|>
<T.ContactList />
<T.TaskLists />
</TrackerPage>
{{/if}}
</TrackerProvider>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment