title: Kendo Grid Grouping on column - TypeError: Cannot read property 'length' of undefined
body: <p>i have problem with grouping data in the Kendo Grid.</p>
  
  <p>I i drag the column which i want to use for group i always got following error. </p>
  
  <pre><code> TypeError: Cannot read property 'length' of undefined
  </code></pre>
  
  <p>I tried to find where error is triggered but without luck.</p>
  
  <p>Grouped data from server are returned back.</p>
  
  <p>Many Thanks for any advice.</p>
  
  <p>GRID INIT CODE:</p>
  
  <pre><code>$scope.initGrid = function() {
  
        console.log("init locations grid");
          // set container for loading spinner
          gridView = $("#locations_grid");
          // set all properties for data grid
          gridView.kendoGrid({
              dataSource: {
                  transport: {
                      // READ REQUEST
                      read: function (options) {
                          console.log("List");
                          console.log(options.data);
                          requestParams = {
                              "entityName": "Location"
                          };
                          requestParams.data = options.data;
  
                          console.log(requestParams);
                          ApiService.doHttpRequest(
                                  "POST",
                                  $rootScope.apiBaseUrl + "location/search",
                                  requestParams
                          )
                          .success(function (data, status, headers, config) {
                              // successful data retrieval
                              console.log("request success, checking state");
                              console.log(data);
                              // sent status to global HTTP status service
                              var jsonResponse =  ApiService.processReturnedHttpState(status);
                              console.log("Status response is " + jsonResponse.result);
                              // do something with data
                              switch (jsonResponse.result) {
                                  case true:
                                      options.success(data);
                                      break;
                                  case false:
                                      growlNotifications.add($translate.instant('LIST_LOADING_ERROR'), 'error',  $rootScope.notificationLifetime);
                                      break;
                              }
                          })
                          .error(function (data, status, headers, config) {
                              var jsonResponse =  ApiService.processReturnedHttpState(status);
                              console.log("Processing error with status " +status);
                              growlNotifications.add($translate.instant('PROCESSING_REQUEST_ERROR') + jsonResponse.message , 'error',  $rootScope.notificationLifetime);
                              // hide loading spinner
                              kendo.ui.progress(gridView, false);
                          });
                      },
                      // DELETE FUNCTION
                      destroy: function (options) {
                          console.log("delete");
                          console.log(options.data);
                          // add data to request params
                          console.log("delete id: " +options.data.id);
                          // call the service
                          ApiService.doHttpRequest(
                              "POST",
                              $rootScope.apiBaseUrl + "/location/delete",
                              requestParams)
                              .success(function (data, status, headers, config) {
                                  // successful data retrieval
                                  console.log("request success, checking state");
                                  console.log(data);
                                  // sent status to global HTTP status service
                                  var jsonResponse =  ApiService.processReturnedHttpState(status);
                                  console.log("Status response is " + jsonResponse.result);
                                  // do something with data
                                  switch (jsonResponse.result) {
                                      case true:
                                          options.success(data);
                                          break;
                                      case false:
                                          growlNotifications.add($translate.instant('LIST_LOADING_ERROR'), 'error',  $rootScope.notificationLifetime);
                                          break;
                                  }
                              })
                              .error(function (data, status, headers, config) {
                                  var jsonResponse =  ApiService.processReturnedHttpState(status);
                                  console.log("Processing error with status " +status);
                                  growlNotifications.add($translate.instant('PROCESSING_REQUEST_ERROR') + jsonResponse.message , 'error',  $rootScope.notificationLifetime);
                                  // hide loading spinner
                                  kendo.ui.progress(gridView, false);
                              });
                      },
                      // CREATE FUNCTION
                      create: function (options) {
                          console.log("Create");
                          console.log(options.data);
                          // ADD DATA FOR UPDATE TO THE TOKEN
                          requestParams = options.data;
                          ApiService.doHttpRequest(
                              "POST",
                              $rootScope.apiBaseUrl + "location/create",
                              requestParams
                          )
                              .success(function (data, status, headers, config) {
                                  // successful data retrieval
                                  console.log("request success, checking state");
                                  console.log(data);
                                  // sent status to global HTTP status service
                                  var jsonResponse =  ApiService.processReturnedHttpState(status);
                                  console.log("Status response is " + jsonResponse.result);
                                  // do something with data
                                  switch (jsonResponse.result) {
                                      case true:
                                          options.success(data);
                                          var dataSource = gridView.dataSource;
                                          gridView.data('kendoGrid').dataSource.read();
                                          growlNotifications.add($translate.instant('SUCCESSFULLY_ADDED'), 'success',  $rootScope.notificationLifetime);
                                          break;
                                      case false:
                                          growlNotifications.add($translate.instant('PROCESSING_ERROR'), 'error',  $rootScope.notificationLifetime);
                                          options.success(data);
                                          break;
                                  }
  
                              })
                              .error(function (data, status, headers, config) {
                                  var jsonResponse =  ApiService.processReturnedHttpState(status);
                                  console.log("Processing error with status " +status);
                                  growlNotifications.add($translate.instant('PROCESSING_REQUEST_ERROR') + jsonResponse.message , 'error',  $rootScope.notificationLifetime);
                                  // hide loading spinner
                                  kendo.ui.progress(gridView, false);
                              });
                      }
                  },
                  requestStart: function(e) {
                      console.log("Request start");
  
  
                  },
                  requestEnd: function(e) {
                    console.log("Request end");
  
                    // hide loading spinner
                    kendo.ui.progress(gridView, false);
  
                  },
                  requestError: function(e) {
                      console.log("Request error");
                      // hide loading spinner
                      kendo.ui.progress(gridView, false);
                  },
                  // SCHEMA FOR DATAGRID
                  schema: {
                      model: {
                          id: "id",
                          fields: {
                              id: {
                                  editable: false,
                                  nullable: true,
                                  defaultValue: null,
                                  type: "number"
                              },
                              accessNote: {
                                  editable: false,
                                  nullable: true,
                                  type: "string"
                              },
                              address: {
                                  editable: false,
                                  defaultValue: {},
                                  nullable: true
                              },
                              bsc: {
                                  editable: false,
                                  nullable: true
                              },
                              code:{
                                  editable: false,
                                  nullable: true,
                                  type: "string",
                                  validation: {
                                      required: true,
                                      min: 1
                                  }
                              },
                              indoorOutdoor:{
                                  editable: false,
                                  nullable: true,
                                  type: "string",
                                  validation: {
                                      required: {
                                          message: $translate.instant('FIELD_IS_REQUIRED')
                                      }
                                  }
                              },
                              siteId:{
                                  editable: false,
                                  nullable: true,
                                  type: "string",
                                  validation: {
                                      required: {
                                          message: $translate.instant('FIELD_IS_REQUIRED')
                                      }
                                  }
                              },
                              shared: {
                                editable: false,
                                nullable: true,
                                type: "boolean"
                              },
                              partner: {
                                nullable: true,
                                editable: false,
                                defaultValue: {},
                              },
                              stationType:{
                                  nullable: true,
                                  editable: false,
                                  defaultValue: {},
  
                              },
                              abloyLocation:{
                                  editable: false,
                                  type: "string",
                                  defaultValue: ""
                              },
                              sapSacIrnCode:{
                                editable: false,
                                type: "string",
                                defaultValue: ""
                              }
                          }
                      },
                      data: function(response) {
                          console.log(response.results);
                          if (response.results.length == 0) {
                            return [];
                          }
                          return response.results;
                      },
                      total: function(response) {
                          console.log(response.resultCount);
                          return response.resultCount;
                      }
                  },
                  // definition for page sorting
                  pageSize : GridHelperService.setDefaultPageSize(),
                  serverPaging: true,
                  serverFiltering: true,
                  serverSorting: true,
                  serverGrouping: true
              },
              editable:{
                  confirmation:true //remove delete confirm message
              },
              scrollable:true,
              //window resizing hack
              height: function () {
                 return GlobalHelperService.getWindowSize();
              },
              filterable: GridHelperService.filtersTranlations(),
              sortable: true,
              groupable : {
                  messages: {
                      empty : $translate.instant('DRAG_SELECTED_COLUMN_HEADER_HERE_TO_GROUP')
                  }
              },
              reorderable: true,
              resizable: true,
              //dataBound: resizeGrid, //callback when data are loaded
              columnMenu: GridHelperService.getColumnMenu(),
              pageable: GridHelperService.getBottomToolbar(),
              messages:GridHelperService.getToolbarButtonsTranlations(),
              toolbar: [
                  { name: "create" },
                  { template: kendo.template($("#template").html()) },
              ],
              columns: [
                  {
                      field :"partner.name",
                      editable: false,
                      title : $translate.instant('PARTNER'),
                      width: 250,
                      template: function(data) {
                        console.log("Data are");
                        try {
                          if(data.partner.name === null) {
                            console.log("Partner is null");
                            return "";
                          } else {
                            return data.partner.name;
                          }
                        } catch (e){
                          return "";
                        }
  
                      },
                      filterable: {
                          cell: {
                              operator: "contains"
                          }
                      }
                  },
                  {
                      field :"accessNote",
                      title : $translate.instant('ACCESS_NOTE'),
                      width: 250,
                      filterable: {
                          cell: {
                              operator: "contains"
                          }
                      }
                  },
                  {
                    field :"abloyLocation",
                    title : $translate.instant('ABBLOY_LOCATION'),
                    width: 250,
                    filterable: {
                      cell: {
                        operator: "contains"
                      }
                    }
                  },
                  {
                      field :"address.city",
                      title : $translate.instant('ADDRESS_CITY'),
                      width: 250,
                      template: function(data) {
                        console.log("Data are");
                        try {
                          if(data.address.city === null) {
                            console.log("Is null");
                            return "";
                          } else {
                            return data.address.city;
                          }
                        } catch (e){
                          return "";
                        }
  
                      },
                      filterable: {
                          cell: {
                              operator: "contains"
                          }
                      }
                  },
                  {
                      field :"address.latitude",
                      title : $translate.instant('ADDRESS_LAT'),
                      width: 250,
                      template: function(dataItem) {
                        console.log("ADDRESS_LON IS FOLLOWING:");
                        try {
                          console.log(dataItem.address.latitude);
                          if(dataItem.address.latitude === null) {
                            return "";
                          } else {
                            console.log("TRYING TO GET LENGTH");
                            var stringLon = dataItem.address.latitude.toString();
                            var lengthOfString = stringLon.toString().length;
                            console.log("LENGTH IS:");
                            console.log(lengthOfString);
                            if(lengthOfString &gt;= 5) {
                              console.log("IS LONG");
                              var trimmedString = stringLon.substring(0, 5);
                              console.log("TRIMMED STRING");
                              console.log(trimmedString);
                              return trimmedString;
                            }
                            else {
                              console.log("IS SHORT");
                              return stringLon;
                            }
                          }
                        } catch (e){
                          console.log("EXC ADDRESS_LAT");
                          return "";
                        }
  
                      },
                      filterable: {
                          cell: {
                              operator: "eq"
                          }
                      }
                  },
                  {
                      field :"address.longitude",
                      title : $translate.instant('ADDRESS_LON'),
                      width: 250,
                      template: function(dataItem) {
                        try{
                          if(dataItem.address.longitude === null) {
                            return "";
                          } else {
                            console.log("TRYING TO GET LENGTH");
                            var stringLon = dataItem.address.longitude.toString();
                            var lengthOfString = stringLon.toString().length;
                            console.log("LENGTH IS:");
                            console.log(lengthOfString);
                            if(lengthOfString &gt;= 5) {
                              console.log("IS LONG");
                              var trimmedString = stringLon.substring(0, 5);
                              console.log("TRIMMED STRING");
                              console.log(trimmedString);
                              var html = "&lt;div&gt;"+trimmedString+"&lt;a class=\"showOnMapBtn\" href=\"http://maps.google.com/maps?q="+dataItem.address.latitude+","+dataItem.address.longitude+"&amp;z=14&amp;ll="+dataItem.address.latitude+","+dataItem.address.longitude+"\" target=\"blank\"&gt;"+$translate.instant('MAP')+"&lt;/a&gt;&lt;/div&gt;";
                              return html;
                            }
                            else {
                              console.log("IS SHORT");
                              var html = "&lt;div&gt;"+stringLon+"&lt;a class=\"showOnMapBtn\" href=\"http://maps.google.com/maps?q="+dataItem.address.latitude+","+dataItem.address.longitude+"&amp;z=14&amp;ll="+dataItem.address.latitude+","+dataItem.address.longitude+"\" target=\"blank\"&gt;"+$translate.instant('MAP')+"&lt;/a&gt;&lt;/div&gt;";
                              return html;
                            }
                            console.log("ADDRESS_LON IS FOLLOWING:");
                            console.log(dataItem.address.longitude);
                          }
                        } catch(e) {
                          console.log("EXC ADDRESS_LON");
                          return "";
                        }
                          },
                      filterable: {
                          cell: {
                              operator: "eq"
                          }
                      }
  
                  },
                  {
                      field :"address.street",
                      title : $translate.instant('ADDRESS_STREET'),
                      width: 250,
                      editor: GlobalHelperService.getAddressStreetListForAutocomplete,
                      template: function(dataItem) {
                        try{
                          if(dataItem.address.street === null) {
                            return "";
                          } else {
                            return dataItem.address.street;
                          }
                        } catch(e) {
                          return "";
                        }
                      },
                      filterable: {
                          cell: {
                              operator: "contains"
                          }
                      }
                  },
                  {
                    field :"address.district",
                    title : $translate.instant('ADDRESS_DISTRICT'),
                    template: function(dataItem) {
                      try{
                        if(dataItem.address.district === null) {
                          return "";
                        } else {
                          return dataItem.address.district;
                        }
                      } catch(e) {
                        return "";
                      }
                    },
                    width: 250,
                    filterable: {
                      cell: {
                        operator: "contains"
                      }
                    }
                  },
                  {
                    field :"address.streetNumber",
                    title : $translate.instant('ADDRESS_STREET_NUMBER'),
                    template: function(dataItem) {
                      try{
                        if(dataItem.address.streetNumber === null) {
                          return "";
                        } else {
                          return dataItem.address.streetNumber;
                        }
                      } catch(e) {
                        return "";
                      }
                    },
                    width: 250,
                    filterable: {
                      cell: {
                        operator: "contains"
                      }
                    }
                  },
                  {
                      field :"bsc",
                      title : $translate.instant('BSC'),
                      width: 250,
                      filterable: {
                          cell: {
                              operator: "contains"
                          }
                      }
                  },
                  {
                      field :"code",
                      title : $translate.instant('CODE'),
                      width: 250,
                      filterable: {
                          cell: {
                              operator: "contains"
                          }
                      }
                  },
                  {
                      field :"indoorOutdoor",
                      title : $translate.instant('INDOOR_OUTDOOR'),
                      editor: GlobalHelperService.locationTypeDropDownEditor,
                      template: function(dataItem) {
                          switch (dataItem.indoorOutdoor)
                          {
                              case "Indoor":
                                  return "Indoor";
                              case "Outdoor":
                                  return "Outdoor";
                              case "IndoorOutdoor":
                                  return "Indoor &amp; Outdoor";
                              default:
                                  return "Neuvedeno";
                          }
                      },
                      width: 250,
                      filterable: {
                          cell: {
                              operator: "contains"
                          }
                      }
                  },
                  {
                      field :"siteId",
                      title : $translate.instant('SITE_ID'),
                      width: 250,
                      filterable: {
                          cell: {
                              operator: "contains"
                          }
                      }
                  },
                  {
                    field :"sapSacIrnCode",
                    title : $translate.instant('SAPSACIRNCODE'),
                    width: 250,
                    filterable: {
                      cell: {
                        operator: "contains"
                      }
                    }
                  },
                  {
                      field :"stationType.name",
                      title : $translate.instant('STATION_TYPE'),
                      editor: GlobalHelperService.getStationTypeListForAutocomplete,
                      template: function(data) {
                       try{
                          console.log("Data are");
                          console.log(data.stationType.name);
                          if (data.stationType.name === null) {
                            return "";
                          } else {
                            return data.stationType.name;
                          }
                        }
                        catch(e) {
                          return "";
                        }
                      },
                      width: 250,
                      filterable: {
                          cell: {
                              operator: "contains"
                          }
                      }
                  },
                  {
                    command:
                      [
                        {
                          name: "detail",
                          click: function(e) {
                            var clickedRow = this.dataItem($(e.currentTarget).closest("tr"));
                            var workerId = clickedRow.id;
                            GlobalHelperService.redirectTo("/locations/detail/"+workerId);
                            return false;
                          }
                        }
                      ],
  
                    title: $translate.instant('ACTIONS'),
                    width: 90,
                    filterable: {
                      cell: {
                        operator: "contains"
                      }
                    },
                    locked: true,
                    lockable: true
                  }
              ]
          });
  
          // HACK FOR ADD NEW RECORD BUTTON CLICK HANDLED BY ANGULAR JS
          $('.k-header').on('click', '.k-grid-add', function(e) {
            e.preventDefault();
            GlobalHelperService.redirectTo("/locations/create");
            return false;
          });
      };
  </code></pre>