Ghost/ghost/admin/app/services/members-stats.js
Kevin Ansfield 514034d329 Fixed and improved members stats "debounced" fetches
no issue

- the "days changed" logic was incorrect so we were always performing new fetches rather than using existing data
- added a minor improvement that returns an in-progress fetch promise if we have one and params haven't changed - avoids triggering unnecessary extra fetches in the rare occasions the chart is re-rendered before a previous stats fetch has finished
2020-05-28 11:11:43 +01:00

45 lines
1.3 KiB
JavaScript

import Service from '@ember/service';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency-decorators';
import {tracked} from '@glimmer/tracking';
export default class MembersStatsService extends Service {
@service ajax;
@service ghostPaths;
@tracked stats = null;
fetch({days}) {
let daysChanged = days !== this._days;
let staleData = this._lastFetched && this._lastFetched - new Date() > 1 * 60 * 1000;
// return an already in-progress promise unless params have changed
if (this._fetchTask.isRunning && !this._forceRefresh && !daysChanged) {
return this._fetchTask.last;
}
// return existing stats unless data is > 1 min old
if (this.stats && !this._forceRefresh && !daysChanged && !staleData) {
return Promise.resolve(this.stats);
}
return this._fetchTask.perform(...arguments);
}
invalidate() {
this._forceRefresh = true;
}
@task
*_fetchTask({days}) {
this._days = days;
this._lastFetched = new Date();
this._forceRefresh = false;
let statsUrl = this.ghostPaths.url.api('members/stats');
let stats = yield this.ajax.request(statsUrl, {data: {days}});
this.stats = stats;
return stats;
}
}