Rey Hali
Rey Hali

Reputation: 98

How to obtain previous and new value from Angular mat-select?

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

Answers (5)

Hossein Mousavi
Hossein Mousavi

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

last_seen_404
last_seen_404

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

Eliseo
Eliseo

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

AVJT82
AVJT82

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

Saif Jerbi
Saif Jerbi

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

Related Questions