telerik / kendo-angular

Issue tracker - Kendo UI for Angular
http://www.telerik.com/kendo-angular-ui/
Other
469 stars 217 forks source link

Kendo DropDownList: valuePrimitive not working if text/value are defined as getters #1750

Closed akloeber closed 5 years ago

akloeber commented 6 years ago

I'm submitting a...

Current behavior

If the value or text properties of the data items used by Kendo DropDownList are defined as getters and valuePrimitive is set to true the following errors occur:

This can be reproduced with the following project on StackBlitz: https://stackblitz.com/edit/angular-uzrpnv

Code:

import { Component } from '@angular/core';

interface DropdownOption {
  text: string;
  value: any;
}

class Size implements DropdownOption {

  label: string;
  id: number;

  get text(): string {
    return this.label;
  }

  get value(): number {
    return this.id;
  }

  constructor(label: string, id: number) {
    this.label = label;
    this.id = id;
  }
}

@Component({
  selector: 'my-app',
  template: `
    <div class="example-config">
        Selected Value: {{selectedValue | json}}
    </div>
    <kendo-dropdownlist 
      textField="text"
      valueField="value"
      [data]="listItems"
      [valuePrimitive]="true"
      [(ngModel)]="selectedValue"
    ></kendo-dropdownlist>
  `
})
export class AppComponent {
    listItems: Array<DropdownOption> = [
      new Size('small', 1),
      new Size('medium', 2),
      new Size('large', 3),
    ];
    selectedValue: DropdownOption = this.listItems[1];
}

Expected behavior

Minimal reproduction of the problem with instructions

Open project on StackBlitz and select an option.

Environment

Package versions:

See StackBlitz project.

rxjs6.2.2
core-js2.5.7
zone.js0.8.26
hammerjs2.0.8
rxjs-compat6.2.2
@angular/core6.1.3
@angular/http6.1.3
@angular/forms6.1.3
@angular/common6.1.3
@angular/router6.1.3
@angular/compiler6.1.3
@angular/animations6.1.3
@telerik/kendo-intl1.4.1
@progress/kendo-charts1.11.1
@progress/kendo-drawing1.5.7
@angular/platform-browser6.1.3
@progress/kendo-date-math1.2.0
@progress/kendo-data-query1.4.1
@progress/kendo-file-saver1.0.6
@progress/kendo-angular-grid3.6.1
@progress/kendo-angular-intl1.5.0
@progress/kendo-angular-l10n1.2.0
@progress/kendo-angular-menu1.0.0
@progress/kendo-angular-label1.2.0
@progress/kendo-angular-popup2.4.1
@progress/kendo-angular-charts3.3.2
@progress/kendo-angular-dialog3.7.0
@progress/kendo-angular-gauges2.3.2
@progress/kendo-angular-inputs3.2.1
@progress/kendo-angular-layout3.1.2
@progress/kendo-angular-ripple1.0.2
@progress/kendo-angular-upload4.1.4
@progress/kendo-angular-buttons4.1.3
@progress/kendo-angular-tooltip1.0.0
@progress/kendo-angular-sortable1.1.1
@progress/kendo-angular-treeview2.3.0
@angular/platform-browser-dynamic6.1.3
@progress/kendo-angular-dropdowns3.0.3
@progress/kendo-angular-dateinputs3.4.4
@progress/kendo-angular-pdf-export1.1.2
@progress/kendo-angular-scrollview2.0.1
@progress/kendo-angular-excel-export2.1.1
@progress/kendo-angular-conversational-ui1.0.0

Browser:

System:

Additional information

Note: the the example project on StackBlitz works if valuePrimitiveis set to true.

The cause for the error is in the function DropDownListComponent.prototype.propof dropdownlist.component.js:

if (usePrimitive) {
  return field && dataItem.hasOwnProperty(field) ? dataItem[field] : dataItem;
}

If field is a getter which is defined on the object's prototype that represents the class then hasOwnProperty() returns false although field refers to a valid (logical) property.

To bypass the error in the example project above you can patch hasOwnProperty() like this:

Size.prototype.hasOwnProperty = function(p) {
  if (p === 'value' || p === 'text') {
    return true;
  }
  return Object.prototype.hasOwnProperty.call(this, p);
}

This resolves all the issues described above.

A correct check for logical properties needs to check for Object.getOwnPropertyDescriptor(Object.getPrototypeOf(dataItem), field).get on the entire prototype chain. Maybe the existence check in DropDownListComponent.prototype.prop should be removed. I do not see any benefit in working around a potential misconfiguration of text resp. value fields that also introduces this kind of issues.

danielkaradachki commented 6 years ago

Seems like duplicate of https://github.com/telerik/kendo-angular/issues/1682

dimitar-pechev commented 5 years ago

@akloeber, we'll provide a fix for the issue shortly.

Closing in favor of #1682 to track the issue status in one place.