Skip to content

Commit 2b25f24

Browse files
committed
fix(uiGrid): Fix race condition in data watcher
The data watch function is creating a condition where promises can get resolved out of order. If you are fetching both cell templates and data over the network, it will operate thusly: 1. Data watch fires with empty data array, it sees there's no columns set up and builds them from the columnDefs. This uses a promise from the preCompileCellTemplates function. 2. The new data comes in, the data watcher sees there's columns set up now so nothing has to be done and it sets the rows to your new data. Yay! 3. The promise from preCompileCellTemplates completes, and the data is updated AGAIN, but this time with the original empty data set, blowing away the data you fetched. This fix changes the operation so we only call buildColumnDefsFromData() when we actually HAVE data to use, and buildColumns() gets called if we either have data OR have columnDefs. Fixes #2053
1 parent 75bd9f0 commit 2b25f24

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

Diff for: src/js/core/directives/ui-grid.js

+23-10
Original file line numberDiff line numberDiff line change
@@ -60,23 +60,36 @@
6060
}
6161
}
6262

63-
function dataWatchFunction(n) {
63+
function dataWatchFunction(newData) {
6464
// gridUtil.logDebug('dataWatch fired');
6565
var promises = [];
6666

67-
if (n) {
68-
if (self.grid.columns.length === ( self.grid.rowHeaderColumns ? self.grid.rowHeaderColumns.length : 0 ) ) {
69-
// gridUil.logDebug('loading cols in dataWatchFunction');
70-
if (!$attrs.uiGridColumns && self.grid.options.columnDefs.length === 0) {
71-
self.grid.buildColumnDefsFromData(n);
72-
}
67+
if (newData) {
68+
if (
69+
// If we have no columns (i.e. columns length is either 0 or equal to the number of row header columns, which don't count because they're created automatically)
70+
self.grid.columns.length === (self.grid.rowHeaderColumns ? self.grid.rowHeaderColumns.length : 0) &&
71+
// ... and we don't have a ui-grid-columns attribute, which would define columns for us
72+
!$attrs.uiGridColumns &&
73+
// ... and we have no pre-defined columns
74+
self.grid.options.columnDefs.length === 0 &&
75+
// ... but we DO have data
76+
n.length > 0
77+
) {
78+
// ... then build the column definitions from the data that we have
79+
self.grid.buildColumnDefsFromData(n);
80+
}
81+
82+
// If we either have some columns defined, or some data defined
83+
if (self.grid.options.columnDefs.length > 0 || newData.length > 0) {
84+
// Build the column set, then pre-compile the column cell templates
7385
promises.push(self.grid.buildColumns()
7486
.then(function() {
75-
self.grid.preCompileCellTemplates();}
76-
));
87+
self.grid.preCompileCellTemplates();
88+
}));
7789
}
90+
7891
$q.all(promises).then(function() {
79-
self.grid.modifyRows(n)
92+
self.grid.modifyRows(newData)
8093
.then(function () {
8194
// if (self.viewport) {
8295
self.grid.redrawInPlace();

0 commit comments

Comments
 (0)