Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 Select Component set initial selection

I am trying to create a select component wrapper in Angular 2 using ngModel. The events all fire off correctly once the selection is changed but I cannot set the initial selection when it's rendered.

This is my component:

@Component({
selector: 'my-dropdown',
inputs: ['selectedItem', 'items', 'label'],
outputs: ['selectedItemChange'],
template: `
<div class="field">
  <label>{{label}}</label>
    <select class="ui search selection dropdown" [ngModel]="selectedItem" (change)="onChange($event.target.value)">
      <option value="" selected>Please Select</option>
      <option *ngFor="#item of items" [value]="item.value">{{item.label}}</option>
    </select>
</div>`
})

export class MyDropdownComponent {

items: DropdownValue[];
selectedItem: DropdownValue;
selectedItemChange: EventEmitter<any> = new EventEmitter();

private onChange(newValue) {

    console.log(newValue);
    this.selectedItem = this.items.find(item => item.value == newValue);
    console.log(this.selectedItem);
    this.selectedItemChange.emit(newValue);
}
}

And I'm using it in the view like this:

<my-dropdown [items]="selectItems" [(selectedItem)]="itemToSelect" [label]="'Please Select'"></my-dropdown>

When I set the itemToSelect value in the parent component on init, it does not set the selected option value in the UI.

I have also tried to use the ngModelChange event but it does not fire a change event.

like image 841
EnlitenedZA Avatar asked Mar 13 '23 04:03

EnlitenedZA


2 Answers

When I set the itemToSelect value in the parent component on init, it does not set the selected option value in the UI.

Assuming you are using ngOnInit() in the parent, you should set value in one of the lifecycle hooks that are called later (because child doesn't yet exist in ngOnInit()), try ngAfterViewInit()...

like image 33
Sasxa Avatar answered Mar 24 '23 08:03

Sasxa


itemToSelect is initially set to an object, so the input property of MyDropdownComponent is initially set to an object. But then in onChange() a string value is emit()ted, which then causes itemToSelect to be set to a string, and hence the input property becomes a string. Not good.

Just consistently use an object and it will work. Also, there is no need to assign this.selectedItem in onChange(), since the selected value will propagate back down from the parent (in general, you should never set input properties in the component – it also looks weird). You can also use ngModelChange now too:

<select class="ui search selection dropdown" [ngModel]="selectedItem.value"
 (ngModelChange)="onChange($event)">

private onChange(newValue) {
    console.log('nv',newValue);
    selectedItem = this.items.find(item => item.value == newValue);
    console.log('si',selectedItem);
    this.selectedItemChange.emit(selectedItem);
  }
}

Plunker

Note that I did not solve the issue of the user selecting "Please select". You'll need to add some logic to onChange() to handle that case.

like image 160
Mark Rajcok Avatar answered Mar 24 '23 10:03

Mark Rajcok