Reputation: 98
Hellow. I'm using angular 6, and agular material, and I have an array of strings, which I display in a mat-select form field. If an user selects one element, and then another, I need to track what was the previous value and what is the new value.
So far, I've been able to obtain current value using $event.value, but I haven't found a way to store or obtain what the previous value was.
<mat-select placeholder="Choose..." (selectionChange) ="checkTitle($event.value);">
<mat-option *ngFor="let option of Titles; trackBy: trackByFn" [value]="option.title">
{{option.title}}
</mat-option>
</mat-select>
So far, I haven't come up with any ideas as to how solve this problem. Help is appreciated.
Upvotes: 7
Views: 18255
Reputation: 3824
Another simple workaround is to use the openedChange
from mat-select
itself and save the current value. the openedChange
will emit data as the mat-select opens and its event
is a boolean.
public onMatSelectOpen(form: AbstractControl): void {
this.prevMatSelectValue = form.value.type;
}
public onMatSelectValueChanges(event): void {
this.currentValue = event.value
}
<mat-form-field appearance="outline">
<mat-label>label</mat-label>
<mat-select
formControlName="item"
(openedChange)="onMatSelectOpen(form)"
(selectionChange)="onMatSelectValueChanges($event)"
>
<mat-option *ngFor="let item of items" [value]="item.id">
{{ item.name }}
</mat-option>
</mat-select>
</mat-form-field>
To get the current value, you can use selectionChange
from mat-select.
Upvotes: 5
Reputation: 202
There's a property for MatList [selected], which takes boolean value as in true or false.
So while updating or selecting a value. Create a key-value pair which will on selection set true.
Upvotes: 0
Reputation: 57939
Complementary the Saif Jeb's answer, if you use a formControl or FormGroup to get/put the value, you can use formControl.valueChanges, that's
<mat-select [formControl]="control">
<mat-option *ngFor="let food of foods" [value]="food.value">
{{food.viewValue}}
</mat-option>
</mat-select>
control=new FormControl()
ngOnInit()
{
this.control.valueChanges.pipe(
startWith(this.control.value),
pairwise()
).subscribe(
([old,value])=>{
console.log(old,value)
}
)
}
It's necesary a startWith(this.control.value) for the first change emit the value
See stackblitz
Upvotes: 11
Reputation: 73357
You could just simply have a variable, to which you store the previous value:
prevVal: string;
checkTitle(newVal) {
if (this.prevVal) {
console.log(this.prevVal, newVal);
// do stuff
}
// after processing, store the new val as the prev val
this.prevVal = val;
}
Upvotes: -2
Reputation: 675
You can handle previous and current value by pushing the value into a Subject, and observe this Subject using the pairwise operator. This operator will emit the previous and the current value of the stream. (https://www.learnrxjs.io/operators/combination/pairwise.html)
example:
export class YOU_COMPONENT{
private data: Subject<any> = new Subject<any>();
checkTitle(value){
this.data.next(value);
}
observeDataChange():Observable<[]>{
// this return an observable of an array that contains [previous, current] data
return this.data.asObservable().pipe(pairwise());
}
}
Upvotes: 5