Select not showing correct value after change

Viewed 52

The following code generates six <select> tags

<span *ngFor="let key of orderedKeys; let i=index;">
                Position {{i + 1}}:
                <select (change)="changePosition($event.target.value, i+1)" >
                    <option *ngFor="let option of options" [value]="option" [selected]="option === object[key].name">{{option}}</option>
                </select>
                <hr>
</span>

The function changePosition swaps the position of two keys in orderedKeys so that the selected option should change for two select tags but one select which should change the value is only focused but is not changing the selected value but why? I also tried it with [(ngModel)]=object[key].name but the same behavior is observed.

1 Answers

It's all about angular change detection... (when nested structural directives combined with conditions and user changes). In such cases we can force update conditions on next browser MacroTask:

<span *ngFor="let key of orderedKeys; let i=index;">
   Position {{i + 1}}:
   <select (change)="changePosition($event.target.value, i+1)" >
     <option *ngFor="let option of options" [value]="option" [selected]="flag && (option === object[key].name)">{{option}}</option>
     </select>
     <hr>
</span>

ts:

orderedKeys = ['keyA', 'keyB', 'keyC', 'keyD'];
  object = {
    'keyA': {name: 'nameA'},
    'keyB': {name: 'nameB'},
    'keyC': {name: 'nameC'},
    'keyD': {name: 'nameD'},
  }
  options = ['nameA', 'nameB', 'nameC', 'nameD'];
  flag = true;

  changePosition(val: string, pos: number) {
    let selectedKey = Object.keys(this.object).find(key => this.object[key].name === val);
    let keyToSwap = this.orderedKeys[pos - 1];
    
    let newOrderedKeys = [...this.orderedKeys];
    newOrderedKeys[pos - 1] = selectedKey;
    newOrderedKeys[this.orderedKeys.indexOf(selectedKey)] = keyToSwap;
    
    this.flag = false;
    setTimeout(() => {
      this.orderedKeys = newOrderedKeys;
      this.flag = true;
    }, 0);
  }

finally in these priority or ranking cases other implementations may be better:

  • reactive forms with FormArray (removeAt and insert fuctions)
  • other Ui components like CDK drag and drop
Related