diff --git a/addons/web/static/src/js/views/graph/graph_model.js b/addons/web/static/src/js/views/graph/graph_model.js index b1bcddb47c2a24ddf0b6e279bef2a88d01fb0c97..112d474378ff84c00fad0f847018ce3eabff4220 100644 --- a/addons/web/static/src/js/views/graph/graph_model.js +++ b/addons/web/static/src/js/views/graph/graph_model.js @@ -187,6 +187,8 @@ return AbstractModel.extend({ var fields = _.map(groupBy, function (groupBy) { return groupBy.split(':')[0]; }); + const loadId = this.loadId ? ++this.loadId : 1; + this.loadId = loadId; if (this.chart.measure !== '__count__') { if (this.fields[this.chart.measure].type === 'many2one') { @@ -209,7 +211,7 @@ return AbstractModel.extend({ fields: fields, groupBy: groupBy, lazy: false, - }).then(self._processData.bind(self, originIndex))); + }).then(self._processData.bind(self, originIndex, loadId))); }); return Promise.all(proms); }, @@ -218,15 +220,14 @@ return AbstractModel.extend({ * depending of some input, we have to normalize the result. * Each group coming from the read_group produces a dataPoint * - * @todo This is not good for race conditions. The processing should get - * the object this.chart in argument, or an array or something. We want to - * avoid writing on a this.chart object modified by a subsequent read_group - * * @private * @param {number} originIndex * @param {any} rawData result from the read_group */ - _processData: function (originIndex, rawData) { + _processData: function (originIndex, loadId, rawData) { + if (loadId < this.loadId) { + return; + } var self = this; var isCount = this.chart.measure === '__count__'; var labels; diff --git a/addons/web/static/tests/views/graph_tests.js b/addons/web/static/tests/views/graph_tests.js index fda4c5cb1901418c1f2f22bdfc5f999ebf580a21..0c5995b8531bbe8ddc58f20114d69a545b667a72 100644 --- a/addons/web/static/tests/views/graph_tests.js +++ b/addons/web/static/tests/views/graph_tests.js @@ -681,6 +681,31 @@ QUnit.module('Views', { graph.destroy(); }); + QUnit.test('only process most recent data for concurrent groupby', async function (assert) { + assert.expect(4); + + const graph = await createView({ + View: GraphView, + model: 'foo', + data: this.data, + arch: ` + <graph> + <field name="product_id" type="row"/> + <field name="foo" type="measure"/> + </graph>`, + }); + + assert.checkLabels(graph, [['xphone'], ['xpad']]); + assert.checkDatasets(graph, 'data', {data: [82, 157]}); + + testUtils.graph.reload(graph, {groupBy: ['color_id']}); + await testUtils.graph.reload(graph, {groupBy: ['date:month']}); + assert.checkLabels(graph, [['January 2016'], ['March 2016'], ['May 2016'], ['Undefined'], ['April 2016']]); + assert.checkDatasets(graph, 'data', {data: [56, 26, 4, 105, 48]}); + + graph.destroy(); + }); + QUnit.test('use a many2one as a measure should work (without groupBy)', async function (assert) { assert.expect(4);