SearchKit - Prevent race conditions in search display loading
authorColeman Watts <coleman@civicrm.org>
Tue, 7 Sep 2021 18:36:58 +0000 (14:36 -0400)
committerColeman Watts <coleman@civicrm.org>
Tue, 7 Sep 2021 18:36:58 +0000 (14:36 -0400)
- Increases debounce timeout from 100 to 800 ms
- Internally tracks the requests to ensure that later requests always take priority

ext/search_kit/ang/crmSearchDisplay/traits/searchDisplayBaseTrait.service.js

index f4700a6b01882f9ae5d4e1c82d0f46f0b8c37605..39b631e0e9907bd870cf03908bb8a795e2664283 100644 (file)
@@ -3,7 +3,8 @@
 
   // Trait provides base methods and properties common to all search display types
   angular.module('crmSearchDisplay').factory('searchDisplayBaseTrait', function(crmApi4) {
-    var ts = CRM.ts('org.civicrm.search_kit');
+    var ts = CRM.ts('org.civicrm.search_kit'),
+      runCount = 0;
 
     // Replace tokens keyed to rowData.
     // Pass view=true to replace with view value, otherwise raw value is used.
@@ -77,7 +78,7 @@
           $scope.$apply(function() {
             ctrl.runSearch();
           });
-        }, 100);
+        }, 800);
 
         // If search is embedded in contact summary tab, display count in tab-header
         var contactTab = $element.closest('.crm-contact-page .ui-tabs-panel').attr('id');
       // Call SearchDisplay.run and update ctrl.results and ctrl.rowCount
       runSearch: function(editedRow) {
         var ctrl = this,
+          requestId = ++runCount;
           apiParams = this.getApiParams();
         this.loading = true;
         _.each(ctrl.onPreRun, function(callback) {
           callback.call(ctrl, apiParams);
         });
         return crmApi4('SearchDisplay', 'run', apiParams).then(function(results) {
+          if (requestId < runCount) {
+            return; // Another request started after this one
+          }
           ctrl.results = results;
           ctrl.editing = ctrl.loading = false;
           if (!ctrl.rowCount) {
             callback.call(ctrl, results, 'success', editedRow);
           });
         }, function(error) {
+          if (requestId < runCount) {
+            return; // Another request started after this one
+          }
           ctrl.results = [];
           ctrl.editing = ctrl.loading = false;
           _.each(ctrl.onPostRun, function(callback) {