0
votes
        <mat-form-field>
            <input matInput
                   [formControl]="affiliationName"
                   [matAutocomplete]="auto">
            <mat-label>Affiliation</mat-label>

            <mat-autocomplete #auto="matAutocomplete">
                <mat-option *ngFor="let item of items"
                            [value]="item.value"
                            (onSelectionChange)="onAffiliationSelect(item)">
                    <span class="semibold">{{item.code}}</span>
                </mat-option>
            </mat-autocomplete>
        </mat-form-field>

In the code-

affiliationName: FormControl;


ngOnInit() {
    this.listenToInput();
}


listenToInput() {
    this.affiliationName
        .valueChanges.pipe(
        debounceTime(300),
        distinctUntilChanged(),takeUntil(this.affiliationDestroy))
            .subscribe(value => {
                  //do something
            });
    }

When the user types in the input field I want to invoke a search in the server side. But after I get my options and the user selects an option and my form control is filled with the chosen option I do not want the valueChanges will be triggered so another search will not be invoked. Is there a way to do it without just adding another formControl or a Boolean variable that will control the server call?

I saw this answer, but it is not my case since I must have an input, so mat-select does not help me. Angular 7 - not triggering "valueChanges" from the template (using mat-option)

2

2 Answers

0
votes

Try to test what kind of emission is coming from valueChanges. If it's a string, it's from the user typing. If it's an object, it comes from a user selection.

For that to work, you must set the mat-option value to the entire object instead of just item.value. Additionally, to show the chosen value on the input, you must add a displayWith attribute to mat-autocomplete. It receives a function that accepts one argument (the mat-option value of the seleted option) and returns a string with the value to be shown on the input control.

<mat-form-field>
  <input matInput
         [formControl]="affiliationName"
         [matAutocomplete]="auto">
  <mat-label>Affiliation</mat-label>
</mat-form-field>

<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn()">
  <mat-option *ngFor="let item of items"
              [value]="item"
              (onSelectionChange)="onAffiliationSelect(item)">
    <span class="semibold">{{item.code}}</span>
  </mat-option>
</mat-autocomplete>
affiliationName: FormControl = new FormControl();

ngOnInit() {
  this.listenToInput();
}

displayFn(): (item: any) => string {
  return (item: any): string => item && item.value ? item.value : '';
}

listenToInput() {
  this.affiliationName 
    .valueChanges.pipe(
      filter((v: any) => typeof v === 'string'),
      debounceTime(300),
      distinctUntilChanged(),
      takeUntil(this.affiliationDestroy)
    ).subscribe(value => {
      //do something
    });
}
0
votes

The FormControl is not initialized, can you try add this to your code?

affiliationName: FormControl = new FormControl();