Search code examples
angularangular-formsangular-ngselect

Angular ng-select - bindValue don't work and still binds to whole object


I have a problem with ng-select (I am using newest version and Angular 10).

I am creating a common component called form-row-select-multiple, which I will be using in many other components. Here is shortened TS file of this component:

  @Input() options: any[] = [];
  @Input() optionKey = 'id'; // in case of options object, specify prop
  @Input() optionKeyText = 'name'; // in case of options object, specify prop to show on option textValue
  @Input() isMultiple = true;
  @Input() selectedValues: any;
  @Output() valueChange: EventEmitter<any> = new EventEmitter();
  elementId: string;

  ngOnInit() {
    if (typeof this.selectedValues === 'object' && this.selectedValues !== null && this.selectedValues.length > 0) {
      this.selectedValues = this.selectedValues.map(value => value[this.optionKey]);
    }
  }

  onChange(event: any) {
    this.valueChange.emit(event);
  }

  trackById(item: any) {
    return item.id;
  }

And HTML of this component:

<ng-select
    [multiple]="isMultiple"
    [id]="elementId"
    [items]="options"
    [(ngModel)]="selectedValues"
    [bindLabel]="optionKeyText"
    [bindValue]="optionKey"
    (add)="onChange($event)"
    [trackByFn]="trackById"
  >

As you can see in TS file, I am passing @Input() options from another component, where I am getting data asynchronously from server. My problem is, that despite of using [bindValue]="optionKey" on , it stills bind its value to the whole object (when I log value of event in onChange function, it logs whole object).

BindLabel works fine, so I am not sure why bindValue not. I thought that it might be because of that [(ngModel)]="selectedValues" is also object, so I implemented a logic in ngOnInit, where if selectedValues are objects, I will do a simple array from that. But that did not resolve my problem.

Do you please have any idea, where the problem might be? No errors showing up in the console. Thank you for all ideas.


Solution

  • The bindValue option determines the model to be held by the variable bound to the ngModel binding, not the event emitted by the add event. So you could instead emit the ngModel bound variable.

    Try the following

    ngOnInit() {
    }
    
    onChange(event: any) {
      this.valueChange.emit(this.selectedValues);
    }
    

    Also the add event is emitted only when options are added to the list and not everytime that value is changed. For that you need to use change event.

    Working example: Stackblitz