1

I was curious if it is possible to use a pipe in displayFn. I use this for a country select, but to avoid dealing the languages in the saved value I just want to just Aplha2 country codes. Hence in the given code example I choose to set the value on the mat-option to the country code of the object.

I tried to use a service within the display function, but its always undefined and i think its because the function is scoped. So anything within the component that is with the display function will be null.

In the html template:

<mat-form-field class="fill">
        <mat-label >Country</mat-label>
        <input matInput placeholder="Search Countries" [matAutocomplete]="auto" formControlName="country">
        
        <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayCountryFn">
            <mat-option *ngIf="countriesLoading" class="is-loading">Loading...</mat-option>
            <ng-container *ngIf="!countriesLoading">
                <mat-option *ngFor="let cc of filteredCountries" [value]="cc.countryCode"> {{cc.countryCode | a2Country}} </mat-option>
            </ng-container>
        </mat-autocomplete>
    </mat-form-field>

in the component.ts file

export class SomeComponent{
...
  constructor(private countryService: CountryService){}
 ...
    displayCountryFn(cc: String){
    //cc is the contryCode
    //this.countryService  is always undefined in this case
    if(this.countrySerivce !=null){
       return this.countryService.fromAplha2(cc);
    }

    return cc;
    }
}

I would not mind mind to make a bit of a hack if required. So lets say i type DK into the input and the value just change to Denmark (in localized language) however in this case i have to watch out cause the input already has a listener on the value that makes a search for country names.

1 Answers1

1

Indeed you need to bind your component's scope to the display function. You can define your display function as an arrow function, so that your function's scope will be your component's scope:

displayCountryFn = (cc: string) => {
    //cc is the contryCode
    if(this.countrySerivce != null){
       return this.countryService.fromAplha2(cc);
    }

    return cc;
}

See here: Binding 'this' in Angular Material Autocomplete displayWith using Angular 5

jbgt
  • 1,586
  • 19
  • 24
  • 1
    I was asking for a pipe, but this is actually a lot better thank you. – Henrik Bøgelund Lavstsen Feb 20 '21 at 14:04
  • Ok, so you would use a pipe in `[displayWith]`, that would then call `countryService` from the pipe's class? I'm not sure whether this would work with `[displayWith]`, maybe you would need the same kind of "hack" to keep the right scope bound to the method. But if it works, it might be better, depending on your architecture, for instance if you need to perform the same conversion in multiple components. – jbgt Feb 21 '21 at 17:22