'Angular Material - Multiple Select - Last selected value
When working with mat-select, you can subscribe to an event "selectionChange".
<mat-select
[(ngModel)]="value"
name="someName"
multiple="true"
(selectionChange)="handleEvent($event)"
>
<mat-option
*ngFor="let val of values"
[value]="val"
>
{{ val }}
</mat-option>
</mat-select>
handleEvent(event: MatSelectChange) {
console.log(event.value); // => array of values
}
This will emit a MatSelectChange where you access the current value of the select.
The problem is, when working with multiple selection, the value property will contains an array with all the currently selected values.
What I need, is to know what was the last value the user selected. I have print out the MatSelectChange event to see if there is anything I could use (like, previous values, so I can compare), but, sadly, I don't see anything.
Is it possible to achieve that ?
Solution 1:[1]
Since I cannot use ReactiveForm and have to stick with Template Driven, I came up with this solution:
<mat-select
[(ngModel)]="value"
name="someName"
multiple="true"
(selectionChange)="mySubject.next($event.value)"
>
And on the other side, when subscribing to the subject:
this.mySubject.pipe(startWith(null), pairwise()).subscribe({
next: (values: number[]) => {
const previousValue = values[0];
const currentValue = values[1];
// previousValue will be null on first call
const newValue = previousValue === null ?
currentValue[0] : currentValue.find((value: number) => !previousValue.includes(value));
}
)
startWith is there because the subject will not emit any value until it has a previous AND a current value.
Solution 2:[2]
You could have use @DaggeJ's solution along with the Template Driven froms as below.
<mat-select
[(ngModel)]="value"
#mySelect="ngModel"
name="someName"
multiple="true"">
<mat-option
*ngFor="let val of values"
[value]="val"
>
{{ val }}
</mat-option>
</mat-select>
@ViewChild('mySelect') mySelect: FormControl;
public ngAfterViewInit() {
this.mySelect.valueChanges.pipe(pairwise()).subscribe(([prev, next]: [any, any]) => {
console.log(prev + ' -> ' + next);
});
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Robouste |
| Solution 2 | PrazSam |
