Components: How to pre-select an option in mat-autocomplete

Created on 19 Jan 2018  路  12Comments  路  Source: angular/components

Question:

How to pre-select an option in mat-autocomplete

What is the expected behavior?

Value to be prefilled in the autocomplete when loading a component for editing.

What is the current behavior?

I am not able to prefill the value which i get from the server.

What are the steps to reproduce?

Below is the Code i am using

component.ts
this.filteredData = this.addDetailsForm.get('product').valueChanges
.debounceTime(400)
.do(value =>
{ let exist = this.myContent.findIndex(t => t.text === value);
if (exist > -1) return;
this._dataService.getSwiftProducts(value).subscribe((res: any[]) => { this.myContent = res; });
}).delay(500).map(() => this.myContent);

component.html
<div class="row">
<label class="col-lg-4 control-label">Product: </label>
<div class="col-lg-5">
<input type="text" class="form-control" (keyup.enter)="chooseFirstOption()" placeholder="Pick one" aria-label="Number" matInput ="product" formControlName="product" [matAutocomplete]="auto">
<p *ngIf="addDetailsForm.controls.product.errors">This field is required!</p>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn"> <mat-option *ngFor="let option of filteredData | async" [value]="option"> {{ option.description }} </mat-option> </mat-autocomplete>
</div>

`

What is the use-case or motivation for changing an existing behavior?

To edit a record

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular : "@angular/core": "^5.0.0",
Material : "@angular/material": "^5.0.0-rc0",
OS: Windows 7
Typescript : "typescript": "^2.6.2"

Most helpful comment

Default value?... well, if you have a default value, the autocomplete will bring you just one option if you set an object to the input value (the default value selected) or a list of possible objects if it is a string. I'm not sure I'm following you... I suppose you have something like this in your code:

<input [formControl]="_inputCtrl" [matAutocomplete]="auto">
<mat-autocomplete #auto>
  <mat-option *ngFor="let option of _options$ | async"
              [value]="option"
              [displayWith]="_displayWithLabel()">
      {{option.label}}
  </mat-option>
</mat-autocomplete>
class MyClass {
  label: string;
  value: any;
}

....

_displayWithLabel = () => (value: MyClass | string): string => {
   return !value 
    ? '' 
    : typeof value === 'string' 
      ? value
      : value.label;
}

....

_options$: Observable<MyClass[]>;
constructor(private _service: MyHttpService) {
  this._options$ = _inputCtrl.valueChanges.pipe(
    startWith(null),
    debounce(300),
    switchMap((value: MyClass | string) => this._getOptions(value))
    takeUntil(this._componentDestroyed$),
  );

  // here you set the default selected value: it should fire the valueChanges event set above and
  // get you a list of options, if there was any based on your default initial value.
  this._inputCtrl.setValue('someDefaultStringToStartWith');
}

private _getOptions(value: MyClass | string): Observable<MyClass[]> {
  if(typeof value === 'string') {
    return this._service.getObjectsByLabel(value);
  } else {
    return of([value])
  }
}

All 12 comments

If you want, close this issue and ask it in stackoverflow. After doing that post the link over here and I'll take a look.

Let's keep github for tracking issues, not doubts.

Please keep GitHub issues for bug reports / feature requests. Better avenues for troubleshooting / questions are stack overflow, gitter, mailing list, etc.

@ApoorvBarwa Have you got a solution for that? I am not getting any help.

@rahulgupta20nov : https://stackoverflow.com/questions/48348645/prefill-mat-autocomplete-in-angular-2-material-2 ... refer to this post and ask me if you have any doubt

@ApoorvBarwa The stackoverflow post you have shared is prefill the material autocomplete, is there a way to pre-select. I myself have tried several ways but it doesn't seen to work. Is it even possible to achieve it or I'm banging my head against the wall for nothing. :(

What do you mean by "pre-select"?

@julianobrasil Some kind of default value set to the component. On click it should list the options.

Default value?... well, if you have a default value, the autocomplete will bring you just one option if you set an object to the input value (the default value selected) or a list of possible objects if it is a string. I'm not sure I'm following you... I suppose you have something like this in your code:

<input [formControl]="_inputCtrl" [matAutocomplete]="auto">
<mat-autocomplete #auto>
  <mat-option *ngFor="let option of _options$ | async"
              [value]="option"
              [displayWith]="_displayWithLabel()">
      {{option.label}}
  </mat-option>
</mat-autocomplete>
class MyClass {
  label: string;
  value: any;
}

....

_displayWithLabel = () => (value: MyClass | string): string => {
   return !value 
    ? '' 
    : typeof value === 'string' 
      ? value
      : value.label;
}

....

_options$: Observable<MyClass[]>;
constructor(private _service: MyHttpService) {
  this._options$ = _inputCtrl.valueChanges.pipe(
    startWith(null),
    debounce(300),
    switchMap((value: MyClass | string) => this._getOptions(value))
    takeUntil(this._componentDestroyed$),
  );

  // here you set the default selected value: it should fire the valueChanges event set above and
  // get you a list of options, if there was any based on your default initial value.
  this._inputCtrl.setValue('someDefaultStringToStartWith');
}

private _getOptions(value: MyClass | string): Observable<MyClass[]> {
  if(typeof value === 'string') {
    return this._service.getObjectsByLabel(value);
  } else {
    return of([value])
  }
}

@julianobrasil Well, take for Eg. In the add new items page the auto complete should not have any value and user can use autocomplete directly. But if you consider the edit page there should be prefilled value. Which the user can remove and then use autocomplete. If the user doesn't wants to change the value why empty such an input field.

myControl = new FormControl(this.defaultValue);
This is how i set the default value to the autocomplete component in material Angular 2+ 馃憤

But if you consider the edit page there should be prefilled value. Which the user can remove and then use autocomplete. If the user doesn't wants to change the value why empty such an input field.

The example above should do it. There's no need to recreate the input control everytime.

this._inputCtrl.setValue(...) is enough.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings