thingsboard-aplcache

Details

diff --git a/ui/src/app/api/data-aggregator.js b/ui/src/app/api/data-aggregator.js
index 01c23c8..ec41536 100644
--- a/ui/src/app/api/data-aggregator.js
+++ b/ui/src/app/api/data-aggregator.js
@@ -20,7 +20,7 @@ export default class DataAggregator {
         this.onDataCb = onDataCb;
         this.tsKeyNames = tsKeyNames;
         this.dataBuffer = {};
-        for (var k in tsKeyNames) {
+        for (var k = 0; k < tsKeyNames.length; k++) {
             this.dataBuffer[tsKeyNames[k]] = [];
         }
         this.startTs = startTs;
@@ -143,7 +143,7 @@ export default class DataAggregator {
     }
 
     updateData() {
-        for (var k in this.tsKeyNames) {
+        for (var k = 0; k < this.tsKeyNames.length; k++) {
             this.dataBuffer[this.tsKeyNames[k]] = [];
         }
         for (var key in this.aggregationMap) {
@@ -193,7 +193,7 @@ function processAggregatedData(data, isCount, noAggregation) {
             aggregationMap[key] = aggKeyData;
         }
         var keyData = data[key];
-        for (var i in keyData) {
+        for (var i = 0; i < keyData.length; i++) {
             var kvPair = keyData[i];
             var timestamp = kvPair[0];
             var value = convertValue(kvPair[1], noAggregation);
@@ -217,7 +217,7 @@ function updateAggregatedData(aggregationMap, isCount, noAggregation, aggFunctio
             aggregationMap[key] = aggKeyData;
         }
         var keyData = data[key];
-        for (var i in keyData) {
+        for (var i = 0; i < keyData.length; i++) {
             var kvPair = keyData[i];
             var timestamp = kvPair[0];
             var value = convertValue(kvPair[1], noAggregation);
diff --git a/ui/src/app/api/datasource.service.js b/ui/src/app/api/datasource.service.js
index 2d561c8..6041cbd 100644
--- a/ui/src/app/api/datasource.service.js
+++ b/ui/src/app/api/datasource.service.js
@@ -44,7 +44,7 @@ function DatasourceService($timeout, $filter, $log, telemetryWebsocketService, t
         }
 
         var subscriptionDataKeys = [];
-        for (var d in datasource.dataKeys) {
+        for (var d = 0; d < datasource.dataKeys.length; d++) {
             var dataKey = datasource.dataKeys[d];
             var subscriptionDataKey = {
                 name: dataKey.name,
@@ -295,7 +295,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
                         }
                         subscriber.onReconnected = function() {
                             var newSubsTw = null;
-                            for (var i2 in listeners) {
+                            for (var i2 = 0; i2 < listeners.length; i2++) {
                                 var listener = listeners[i2];
                                 if (!newSubsTw) {
                                     newSubsTw = listener.updateRealtimeSubscription();
@@ -454,7 +454,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
         var value = dataKey.func(time, prevSeries[1]);
         series.push(value);
         datasourceData[dataKey.key].data = [series];
-        for (var i in listeners) {
+        for (var i = 0; i < listeners.length; i++) {
             var listener = listeners[i];
             listener.dataUpdated(datasourceData[dataKey.key],
                 listener.datasourceIndex,
@@ -566,7 +566,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
                     }
                     if (datasourceSubscription.type === types.widgetType.timeseries.value) {
                         var series, time, value;
-                        for (var i in keyData) {
+                        for (var i = 0; i < keyData.length; i++) {
                             series = keyData[i];
                             time = series[0];
                             value = convertValue(series[1]);
@@ -593,7 +593,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
                     }
                     if (update) {
                         datasourceData[datasourceKey].data = data;
-                        for (var i2 in listeners) {
+                        for (var i2 = 0; i2 < listeners.length; i2++) {
                             var listener = listeners[i2];
                             if (angular.isFunction(listener))
                               continue;
diff --git a/ui/src/app/api/device.service.js b/ui/src/app/api/device.service.js
index 60ccad3..2c4a100 100644
--- a/ui/src/app/api/device.service.js
+++ b/ui/src/app/api/device.service.js
@@ -160,7 +160,7 @@ function DeviceService($http, $q, $filter, userService, telemetryWebsocketServic
 
     function devicesToDevicesInfo(devices) {
         var devicesInfo = [];
-        for (var d in devices) {
+        for (var d = 0; d < devices.length; d++) {
             devicesInfo.push(deviceToDeviceInfo(devices[d]));
         }
         return devicesInfo;
@@ -376,7 +376,7 @@ function DeviceService($http, $q, $filter, userService, telemetryWebsocketServic
                 if (query) {
                     var dataKeys = response.data;
                     var lowercaseQuery = angular.lowercase(query);
-                    for (var i in dataKeys) {
+                    for (var i=0; i<dataKeys.length;i++) {
                         if (angular.lowercase(dataKeys[i]).indexOf(lowercaseQuery) === 0) {
                             result.push(dataKeys[i]);
                         }
@@ -526,7 +526,7 @@ function DeviceService($http, $q, $filter, userService, telemetryWebsocketServic
     function saveDeviceAttributes(deviceId, attributeScope, attributes) {
         var deferred = $q.defer();
         var attributesData = {};
-        for (var a in attributes) {
+        for (var a=0; a<attributes.length;a++) {
             attributesData[attributes[a].key] = attributes[a].value;
         }
         var url = '/api/plugins/telemetry/' + deviceId + '/' + attributeScope;
diff --git a/ui/src/app/api/telemetry-websocket.service.js b/ui/src/app/api/telemetry-websocket.service.js
index 9d26089..e03aafa 100644
--- a/ui/src/app/api/telemetry-websocket.service.js
+++ b/ui/src/app/api/telemetry-websocket.service.js
@@ -94,7 +94,7 @@ function TelemetryWebsocketService($rootScope, $websocket, $timeout, $window, ty
         }
         if (isReconnect) {
             isReconnect = false;
-            for (var r in reconnectSubscribers) {
+            for (var r=0; r<reconnectSubscribers.length;r++) {
                 var reconnectSubscriber = reconnectSubscribers[r];
                 if (reconnectSubscriber.onReconnected) {
                     reconnectSubscriber.onReconnected();
@@ -136,7 +136,7 @@ function TelemetryWebsocketService($rootScope, $websocket, $timeout, $window, ty
                     if (!data.data) {
                         data.data = {};
                     }
-                    for (var k in keys) {
+                    for (var k = 0; k < keys.length; k++) {
                         var key = keys[k];
                         if (!data.data[key]) {
                             data.data[key] = [];
diff --git a/ui/src/app/api/user.service.js b/ui/src/app/api/user.service.js
index 4d98d2d..ad401df 100644
--- a/ui/src/app/api/user.service.js
+++ b/ui/src/app/api/user.service.js
@@ -157,18 +157,14 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, toas
     }
 
     function resolveRefreshTokenQueue(data) {
-        for (var q in refreshTokenQueue) {
-            if (isNaN(q))
-              continue;
+        for (var q=0; q < refreshTokenQueue.length;q++) {
             refreshTokenQueue[q].resolve(data);
         }
         refreshTokenQueue = [];
     }
 
     function rejectRefreshTokenQueue(message) {
-        for (var q in refreshTokenQueue) {
-            if (isNaN(q))
-              continue;
+        for (var q=0;q<refreshTokenQueue.length;q++) {
             refreshTokenQueue[q].reject(message);
         }
         refreshTokenQueue = [];
@@ -246,7 +242,7 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, toas
                                 dashboardService.getCustomerDashboards(currentUser.customerId, pageLink).then(
                                     function success(result) {
                                         var dashboards = result.data;
-                                        for (var d in dashboards) {
+                                        for (var d=0;d<dashboards.length;d++) {
                                             allowedDashboardIds.push(dashboards[d].id.id);
                                         }
                                         deferred.resolve();
diff --git a/ui/src/app/app.js b/ui/src/app/app.js
index 5e09b38..e3b36e3 100644
--- a/ui/src/app/app.js
+++ b/ui/src/app/app.js
@@ -13,6 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+import './ie.support';
 import angular from 'angular';
 import ngMaterial from 'angular-material';
 import ngMdIcons from 'angular-material-icons';
diff --git a/ui/src/app/components/dashboard.tpl.html b/ui/src/app/components/dashboard.tpl.html
index ef03145..8c42278 100644
--- a/ui/src/app/components/dashboard.tpl.html
+++ b/ui/src/app/components/dashboard.tpl.html
@@ -24,7 +24,6 @@
 		<div ng-class="vm.dashboardClass" id="gridster-background" style="height: auto; min-height: 100%;">
 			<div id="gridster-child" gridster="vm.gridsterOpts">
 				<ul>
-		<!-- 			    			ng-click="widgetClicked($event, widget)"  -->
 					<li gridster-item="vm.widgetItemMap" class="tb-noselect" ng-repeat="widget in vm.widgets">
 						<md-menu md-position-mode="target target" tb-mousepoint-menu>
 							<div tb-expand-fullscreen
diff --git a/ui/src/app/components/details-sidenav.directive.js b/ui/src/app/components/details-sidenav.directive.js
index d0be111..1ae77fc 100644
--- a/ui/src/app/components/details-sidenav.directive.js
+++ b/ui/src/app/components/details-sidenav.directive.js
@@ -76,7 +76,7 @@ function DetailsSidenav($timeout) {
             detailsButtons: '?detailsButtons'
         },
         scope: {
-            headerTitle: '=',
+            headerTitle: '@',
             headerSubtitle: '@',
             headerHeightPx: '@',
             isReadOnly: '=',
diff --git a/ui/src/app/components/grid.tpl.html b/ui/src/app/components/grid.tpl.html
index c377bec..05eb350 100644
--- a/ui/src/app/components/grid.tpl.html
+++ b/ui/src/app/components/grid.tpl.html
@@ -61,7 +61,7 @@
         </md-virtual-repeat-container>
     </div>
     <tb-details-sidenav
-            header-title="vm.getItemTitleFunc(vm.operatingItem())"
+            header-title="{{vm.getItemTitleFunc(vm.operatingItem())}}"
             header-subtitle="{{vm.itemDetailsText()}}"
             is-read-only="vm.isDetailsReadOnly(vm.operatingItem())"
             is-open="vm.detailsConfig.isDetailsOpen"
diff --git a/ui/src/app/components/widget.controller.js b/ui/src/app/components/widget.controller.js
index ccda4d6..6307a87 100644
--- a/ui/src/app/components/widget.controller.js
+++ b/ui/src/app/components/widget.controller.js
@@ -341,9 +341,9 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
              $scope.legendConfig.showTotal === true);
 
         if (widget.type !== types.widgetType.rpc.value && widget.type !== types.widgetType.static.value) {
-            for (var i in widgetContext.datasources) {
+            for (var i = 0; i < widgetContext.datasources.length; i++) {
                 var datasource = widgetContext.datasources[i];
-                for (var a in datasource.dataKeys) {
+                for (var a = 0; a < datasource.dataKeys.length; a++) {
                     var dataKey = datasource.dataKeys[a];
                     dataKey.pattern = angular.copy(dataKey.label);
                     var datasourceData = {
@@ -723,7 +723,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
     function checkSubscriptions() {
         if (widget.type !== types.widgetType.rpc.value) {
             var subscriptionsChanged = false;
-            for (var i in datasourceListeners) {
+            for (var i = 0; i < datasourceListeners.length; i++) {
                 var listener = datasourceListeners[i];
                 var deviceId = null;
                 var aliasName = null;
@@ -748,7 +748,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
 
     function unsubscribe() {
         if (widget.type !== types.widgetType.rpc.value) {
-            for (var i in datasourceListeners) {
+            for (var i = 0; i < datasourceListeners.length; i++) {
                 var listener = datasourceListeners[i];
                 datasourceService.unsubscribeFromDatasource(listener);
             }
@@ -805,7 +805,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
                 }
             }
             var index = 0;
-            for (var i in widgetContext.datasources) {
+            for (var i = 0; i < widgetContext.datasources.length; i++) {
                 var datasource = widgetContext.datasources[i];
                 if (angular.isFunction(datasource))
                     continue;
diff --git a/ui/src/app/dashboard/dashboard.tpl.html b/ui/src/app/dashboard/dashboard.tpl.html
index 03a177e..ad9e52b 100644
--- a/ui/src/app/dashboard/dashboard.tpl.html
+++ b/ui/src/app/dashboard/dashboard.tpl.html
@@ -153,7 +153,7 @@
             </tb-dashboard>
         </div>
         <tb-details-sidenav class="tb-widget-details-sidenav"
-                            header-title="vm.editingWidget.config.title"
+                            header-title="{{vm.editingWidget.config.title}}"
                             header-subtitle="{{vm.editingWidgetSubtitle}}"
                             is-read-only="false"
                             is-open="vm.isEditingWidget"
@@ -175,7 +175,7 @@
             </form>
         </tb-details-sidenav>
         <tb-details-sidenav ng-if="!vm.widgetEditMode" class="tb-select-widget-sidenav"
-                            header-title="'dashboard.select-widget-title' | translate"
+                            header-title="{{'dashboard.select-widget-title' | translate}}"
                             header-height-px="120"
                             is-read-only="true"
                             is-open="vm.isAddingWidget"
@@ -249,7 +249,6 @@
                       class="md-headline tb-absolute-fill">widget.select-widgets-bundle</span>
             </div>
         </tb-details-sidenav>
-        <!-- </section> -->
         <section layout="row" layout-wrap class="tb-footer-buttons md-fab" layout-align="start end">
             <md-fab-speed-dial ng-disabled="loading" ng-show="!vm.isAddingWidget && vm.isEdit && !vm.widgetEditMode"
                                md-open="vm.addItemActionsOpen" class="md-scale" md-direction="up">
diff --git a/ui/src/app/device/attribute/attribute-table.directive.js b/ui/src/app/device/attribute/attribute-table.directive.js
index 954242e..560a4dc 100644
--- a/ui/src/app/device/attribute/attribute-table.directive.js
+++ b/ui/src/app/device/attribute/attribute-table.directive.js
@@ -275,7 +275,7 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS
                 dataKeys: []
             }
             var i = 0;
-            for (var attr in scope.selectedAttributes) {
+            for (var attr =0; attr < scope.selectedAttributes.length;attr++) {
                 var attribute = scope.selectedAttributes[attr];
                 var dataKey = {
                     name: attribute.key,
diff --git a/ui/src/app/ie.support.js b/ui/src/app/ie.support.js
new file mode 100644
index 0000000..f540a30
--- /dev/null
+++ b/ui/src/app/ie.support.js
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+(function () {
+    if (!String.prototype.startsWith) {
+        String.prototype.startsWith = function(searchString, position) {
+            position = position || 0;
+            return this.indexOf(searchString, position) === position;
+        };
+    }
+    if (!String.prototype.endsWith) {
+        String.prototype.endsWith = function (suffix) {
+            return this.indexOf(suffix, this.length - suffix.length) !== -1;
+        };
+    }
+})();
\ No newline at end of file
diff --git a/ui/src/app/layout/home.tpl.html b/ui/src/app/layout/home.tpl.html
index c259b2f..31c8e7f 100644
--- a/ui/src/app/layout/home.tpl.html
+++ b/ui/src/app/layout/home.tpl.html
@@ -25,8 +25,8 @@
 			  md-is-locked-open="vm.isLockSidenav"
 			  layout="column">
       <header class="tb-nav-header">
-          <md-toolbar md-scroll-shrink class="tb-nav-header-toolbar">
-          	 <div flex layout="row" layout-align="start center" class="md-toolbar-tools inset">
+          <md-toolbar class="tb-nav-header-toolbar">
+          	 <div flex layout="row" layout-align="start start" class="md-toolbar-tools inset">
 				<md-icon md-svg-src="{{vm.logoSvg}}" aria-label="logo" class="tb-logo-title"></md-icon>
           	 </div>
           </md-toolbar>
diff --git a/ui/src/app/widget/lib/flot-widget.js b/ui/src/app/widget/lib/flot-widget.js
index 6f8530f..446881d 100644
--- a/ui/src/app/widget/lib/flot-widget.js
+++ b/ui/src/app/widget/lib/flot-widget.js
@@ -33,7 +33,7 @@ export default class TbFlot {
         this.chartType = chartType || 'line';
 
         var colors = [];
-        for (var i in ctx.data) {
+        for (var i = 0; i < ctx.data.length; i++) {
             var series = ctx.data[i];
             colors.push(series.dataKey.color);
             var keySettings = series.dataKey.settings;
@@ -61,7 +61,7 @@ export default class TbFlot {
         }
         ctx.tooltip = $('#flot-series-tooltip');
         if (ctx.tooltip.length === 0) {
-            ctx.tooltip = $("<div id=flot-series-tooltip' class='flot-mouse-value'></div>");
+            ctx.tooltip = $("<div id='flot-series-tooltip' class='flot-mouse-value'></div>");
             ctx.tooltip.css({
                 fontSize: "12px",
                 fontFamily: "Roboto",
@@ -85,7 +85,7 @@ export default class TbFlot {
             divElement.css({
                 display: "flex",
                 alignItems: "center",
-                justifyContent: "center"
+                justifyContent: "flex-start"
             });
             var lineSpan = $('<span></span>');
             lineSpan.css({
@@ -147,7 +147,7 @@ export default class TbFlot {
                     fontWeight: "700"
                 });
                 content += dateDiv.prop('outerHTML');
-                for (var i in hoverInfo.seriesHover) {
+                for (var i = 0; i < hoverInfo.seriesHover.length; i++) {
                     var seriesHoverInfo = hoverInfo.seriesHover[i];
                     if (tbFlot.ctx.tooltipIndividual && seriesHoverInfo.index !== seriesIndex) {
                         continue;
@@ -333,7 +333,7 @@ export default class TbFlot {
             this.ctx.pieData = angular.copy(this.ctx.data);
             this.ctx.pieRenderedData = [];
             this.ctx.pieTargetData = [];
-            for (i in this.ctx.data) {
+            for (i = 0; i < this.ctx.data.length; i++) {
                 this.ctx.pieTargetData[i] = (this.ctx.data[i].data && this.ctx.data[i].data[0])
                     ? this.ctx.data[i].data[0][1] : 0;
             }
@@ -929,7 +929,7 @@ export default class TbFlot {
     }
 
     pieDataRendered() {
-        for (var i in this.ctx.pieTargetData) {
+        for (var i = 0; i < this.ctx.pieTargetData.length; i++) {
             var value = this.ctx.pieTargetData[i] ? this.ctx.pieTargetData[i] : 0;
             this.ctx.pieRenderedData[i] = value;
             if (!this.ctx.pieData[i].data[0]) {
@@ -943,7 +943,7 @@ export default class TbFlot {
         if (start) {
             this.finishPieDataAnimation();
             this.ctx.pieAnimationStartTime = this.ctx.pieAnimationLastTime = Date.now();
-            for (var i in this.ctx.data) {
+            for (var i = 0;  i < this.ctx.data.length; i++) {
                 this.ctx.pieTargetData[i] = (this.ctx.data[i].data && this.ctx.data[i].data[0])
                     ? this.ctx.data[i].data[0][1] : 0;
             }
@@ -968,7 +968,7 @@ export default class TbFlot {
             this.finishPieDataAnimation();
         } else {
             if (elapsed >= 40) {
-                for (var i in this.ctx.pieTargetData) {
+                for (var i = 0; i < this.ctx.pieTargetData.length; i++) {
                     var prevValue = this.ctx.pieRenderedData[i];
                     var targetValue = this.ctx.pieTargetData[i];
                     var value = prevValue + (targetValue - prevValue) * progress;
diff --git a/ui/src/app/widget/lib/google-map.js b/ui/src/app/widget/lib/google-map.js
index ef9d61b..9722839 100644
--- a/ui/src/app/widget/lib/google-map.js
+++ b/ui/src/app/widget/lib/google-map.js
@@ -91,7 +91,7 @@ export default class TbGoogleMap {
                 function success() {
                     gmGlobals.gmApiKeys[tbMap.apiKey].loaded = true;
                     initGoogleMap();
-                    for (var p in gmGlobals.gmApiKeys[tbMap.apiKey].pendingInits) {
+                    for (var p = 0; p < gmGlobals.gmApiKeys[tbMap.apiKey].pendingInits.length; p++) {
                         var pendingInit = gmGlobals.gmApiKeys[tbMap.apiKey].pendingInits[p];
                         pendingInit();
                     }
diff --git a/ui/src/app/widget/lib/map-widget.js b/ui/src/app/widget/lib/map-widget.js
index fdb7f11..be7b118 100644
--- a/ui/src/app/widget/lib/map-widget.js
+++ b/ui/src/app/widget/lib/map-widget.js
@@ -364,7 +364,7 @@ export default class TbMapWidget {
             var bounds = tbMap.map.createBounds();
             tbMap.locations = [];
             var dataMap = toLabelValueMap(data);
-            for (var l in tbMap.locationsSettings) {
+            for (var l=0; l < tbMap.locationsSettings.length; l++) {
                 var locationSettings = tbMap.locationsSettings[l];
                 var latIndex = -1;
                 var lngIndex = -1;
@@ -398,7 +398,7 @@ export default class TbMapWidget {
             var locationsChanged = false;
             var bounds = tbMap.map.createBounds();
             var dataMap = toLabelValueMap(data);
-            for (var p in tbMap.locations) {
+            for (var p = 0; p < tbMap.locations.length; p++) {
                 var location = tbMap.locations[p];
                 locationsChanged |= updateLocation(location, data, dataMap);
                 if (location.polyline) {
@@ -421,11 +421,11 @@ export default class TbMapWidget {
                 }
             }
             var tooltips = this.map.getTooltips();
-            for (var t in tooltips) {
+            for (var t=0; t < tooltips.length; t++) {
                 var tooltip = tooltips[t];
                 var text = tooltip.pattern;
                 var replaceInfo = tooltip.replaceInfo;
-                for (var v in replaceInfo.variables) {
+                for (var v = 0; v < replaceInfo.variables.length; v++) {
                     var variableInfo = replaceInfo.variables[v];
                     var txtVal = '';
                     if (variableInfo.dataKeyIndex > -1) {
@@ -451,11 +451,11 @@ export default class TbMapWidget {
             this.map.invalidateSize();
             if (this.locations && this.locations.size > 0) {
                 var bounds = this.map.createBounds();
-                for (var m in this.markers) {
+                for (var m = 0; m < this.markers.length; m++) {
                     this.map.extendBoundsWithMarker(bounds, this.markers[m]);
                 }
                 if (this.polylines) {
-                    for (var p in this.polylines) {
+                    for (var p = 0; p < this.polylines.length; p++) {
                         this.map.extendBounds(bounds, this.polylines[p]);
                     }
                 }
diff --git a/ui/src/app/widget/widget-editor.controller.js b/ui/src/app/widget/widget-editor.controller.js
index f510435..24f8fc7 100644
--- a/ui/src/app/widget/widget-editor.controller.js
+++ b/ui/src/app/widget/widget-editor.controller.js
@@ -343,7 +343,7 @@ export default function WidgetEditorController(widgetService, userService, types
                             }
                         };
                     }
-                    for (var i in config.datasources) {
+                    for (var i = 0; i < config.datasources.length; i++) {
                         var datasource = config.datasources[i];
                         datasource.type = vm.widget.type;
                         if (vm.widget.type !== types.widgetType.timeseries.value && datasource.intervalSec) {
@@ -455,7 +455,7 @@ export default function WidgetEditorController(widgetService, userService, types
     }
 
     function onDividerDrag() {
-        for (var i in ace_editors) {
+        for (var i = 0; i < ace_editors.length; i++) {
             var ace = ace_editors[i];
             ace.resize();
             ace.renderer.updateFull();