I'm trying to use a task's isRunning
property to show a spinner while a task is pending. (isRunning
is computed based on the task's concurrency
count.)
When I yield an ember-concurrency timeout()
, or a promise that uses setTimeout()
, the spinner behaves as expected. However, when I yield an Ember Data query (a promise), there is a delay before the spinner shows.
A strange workaround: If I put an additional yield timeout(0);
before the actual promise I'm waiting for, the spinner spins as expected. (It doesn't matter what number I pass to timeout()
.)
(I'm using mirage to fake the API responses, if that comes into play. The spinner does not spin while mirage's handlers are executing.)
Component template:
<button {{action 'submit'}}>
{{#if submitTask.isRunning}}
Wait... <img src="spinner.gif">
{{else}}
Submit
{{/if}}
</button>
Works
This version of the component shows the spinner while the promise is not yet resolved:
export default Ember.Component.extend({
actions: {
submit() {
this.get('submitTask').perform();
}
},
submitTask: task(function * () {
yield timeout(1000);
})
});
This also shows the spinner:
export default Ember.Component.extend({
actions: {
submit() {
this.get('submitTask').perform();
}
},
submitTask: task(function * () {
yield new Ember.RSVP.Promise((resolve) => {
setTimeout(function() {
resolve();
}, 1000);
});
})
});
Passing yield timeout(0)
as a workaround:
export default Ember.Component.extend({
actions: {
submit() {
this.get('submitTask').perform();
}
},
submitTask: task(function * () {
yield timeout(0);
yield this.get('store').query('thing', { whatever });
})
});
Does not work
This does NOT show the spinner (the query still fires and gets the correct results):
export default Ember.Component.extend({
actions: {
submit() {
this.get('submitTask').perform();
}
},
submitTask: task(function * () {
yield this.get('store').query('thing', { whatever });
})
});
This also does NOT show the spinner (the query still fires and gets the correct results):
export default Ember.Component.extend({
actions: {
submit() {
this.get('submitTask').perform();
}
},
submitTask: task(function * () {
yield new Ember.RSVP.Promise((resolve) => {
this.get('store').query('thing', { whatever })
.then(() => resolve());
});
})
});