An Angular material is an amazing UI for Angular framework, it has lots of pre-built components like card, modal, more, and Angular material expansion panel or Angular material autocomplete is one of them.
In this tutorial, first will learn how to use Angular material autocomplete component and second how to use Angular material autocomplete with API call. Let’s get started.
Step 1: Setting up and configure Angular material autocomplete project
Let first create our Angular material autocomplete project and we have two examples of it. Before starting an angular project you need to install nodejs and Angular CLI in your system.
ng new autoCompleteeApp
cd autoCompleteeApp
ng add @angular/material
While running the 3rd command will ask you the select theme, material typography, and animation, press yes on all. To use the Angular material component, we have to import it into our app module. Let create a module and import all material components on it.
ng g m ng-material
To use the Angular material accordion, we need to import MatExpansionModule in our custom module. It is up to you to add all material modules in a separate custom module or root module app. We are adding all material modules in a custom module, it containing only the material module.
Open src/app/ng-material/ng-material.module.ts and replace the existing code with the code shown below and we need the following material component for our example.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
@NgModule({
declarations: [],
imports: [
CommonModule,
MatAutocompleteModule,
MatFormFieldModule,
MatInputModule
],
exports: [
MatAutocompleteModule,
MatFormFieldModule,
MatInputModule
]
})
export class NgMaterialModule { }
We are importing all the required modules in our custom material module file and keeping separate modules for Angular material will make the application easy to maintain. We also need to Form and HttpClient module to demonstrate Angular material autocomplete or angular material typeahead. Now we need to import our material module in the src/app/app.module.ts file.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgMaterialModule } from './ng-material/ng-material.module';
import { HttpClientModule } from '@angular/common/http'
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
FormsModule,
ReactiveFormsModule,
NgMaterialModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
To demonstrate the material list we need dummy data, create folder data in assets and states.json file and add the following dummy data.
{
"states": [
{ "name": "Alabama" },
{ "name": "Alaska" },
{ "name": "Arizona" },
{ "name": "Arkansas" },
{ "name": "California" },
{ "name": "Colorado" },
{ "name": "Connecticut" },
{ "name": "Delaware" },
{ "name": "Florida" },
{ "name": "Georgia" },
{ "name": "Hawaii" },
{ "name": "Idaho" }
]
}
Step 2 : Angular material autocomplete example
We have completed the configuration of the project, let us demonstrate our first example that uses most of the components and directives needed for creating an Angular material expansion panel. Here is a screenshot of our first example.
Let edit the app.component.html template to add our Angular material autocomplete component.
<div class="container">
<section>
<form class="example-form">
<mat-form-field class="example-full-width" appearance="fill">
<mat-label>Angular Material autocomplete</mat-label>
<input type="text"
placeholder="Select country"
aria-label="Country"
matInput
[formControl]="myControl"
[matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption
#auto="matAutocomplete">
<mat-option *ngFor="let option of countryFilteredOptions | async"
[value]="option">
{{option}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
</section>
<router-outlet></router-outlet>
</div>
import { Component } from '@angular/core';
import { FormControl, FormBuilder } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
myControl = new FormControl();
coutries: string[] = ['France', 'India', 'USA', 'Germany', 'Japan'];
countryFilteredOptions: Observable<string[]> | undefined;
constructor(private formBuilder: FormBuilder) {}
ngOnInit(): void {
this.countryFilteredOptions = this.myControl.valueChanges.pipe(
startWith(''),
map(value => this._filter(value))
);
}
private _filter(value: string): string[] {
const filterValue = value.toLowerCase();
return this.coutries.filter(country =>
country.toLowerCase().includes(filterValue));
}
}
Angular material autocomplete properties
Angular material typeahead component has component and sub-component. Here have listed some of the mat autocomplete components.
Name | Properties |
mat-autocomplete | The mat-autocomplete is a root container containing a list of options. We can add data binding and formControl on it. |
mat-option | Sub-component of mat-select and we add individual option item of unique value on it. |
mat-optgroup | Optional sub-component of mat-select and we can group related options. |
auto | The auto attribute needs to link input with autocomplete component by passing the reference of the input element. |
Angular material autocomplete with API call
We’ll demonstrate Angular material autocomplete with API call using HTTP GET method. We have already created a typeahead service to retrieve our dummy data. Here is a screenshot.
Let add the mat autocomplete component in our template, edit the app.component.html file.
<div class="container">
<section>
<mat-form-field>
<input type="text" placeholder="Enter state" [formControl]="myControl"
matInput [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of filterRegions | async"
[value]="option.name">
{{option.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</section>
<router-outlet></router-outlet>
</div>
import { Component } from '@angular/core';
import { FormGroup, FormControl, FormBuilder } from '@angular/forms';
import { Observable } from 'rxjs';
import { TypeaheadService } from './services/typeahead.service';
import { distinctUntilChanged, startWith, switchMap } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
myControl = new FormControl();
form!: FormGroup;
filterRegions: Observable<any> | undefined;
data: string[] = [];
constructor(private formBuilder: FormBuilder,
private http: HttpClient,
private typeahead: TypeaheadService) {
this.filterRegions = this.myControl.valueChanges.pipe(
startWith(''),
distinctUntilChanged(),
switchMap((name: string) => {
return this.typeahead.getStates(name)
})
)
}
}
Create autocomplete service
We need to create a service called the typeahead.service.ts in the services folder by running the following command.
ng g service services/typeahead
In a real application, we might use angular material autocomplete at any part of the application. We need to have a service for angular autocomplete and in our example, we have used autocomplete of one data source. In typeahead.service.ts file edit service to retrieve, filter Angular autocomplete task.
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class TypeaheadService {
constructor(private http: HttpClient) { }
getStates(term: string): Observable<string[]> {
return new Observable((observer) => {
let getStatesNamePromise: Promise<any>;
getStatesNamePromise = new Promise((resolve) => {
this.http.get<string[]>('./assets/data/states.json')
.subscribe((data: any) => {
resolve(data.states);
});
});
getStatesNamePromise.then((data) => {
if (term) {
data = data.filter((x: any) =>
x.name.toLocaleLowerCase().indexOf(term.toLocaleLowerCase()) > -1);
}
observer.next(data);
});
});
}
}
Angular material autocomplete example with image
Angular material autocomplete option we can add image also, here have our last example on material autocomplete.
To demonstrate this example we need dummy data, let’s add countries.json in our assets/data/countries.json file
[
{
"name": "France",
"flag": "c/c3/Flag_of_France.svg",
"area": 640679,
"population": 64979548,
"description": "France, the largest country in Western Europe"
},
{
"name": "India",
"flag": "4/41/Flag_of_India.svg",
"area": 3287263,
"population": 1324171354,
"description": "India (Hindi: Bhārat), officially the Republic of India"
},
{
"name": "Germany",
"flag": "b/ba/Flag_of_Germany.svg",
"area": 357114,
"population": 82114224,
"description": "Germany is a country located in the western Europe"
}
]
Let’s edit the app.compoenent.html template.
<section>
<mat-form-field class="example-full-width">
<input type="text" placeholder="Pick one" aria-label="Number" matInput [matAutocomplete]="auto"
[formControl]="countryCtrl">
<mat-autocomplete #auto="matAutocomplete" (keyup)="getRegions($event)">
<mat-option *ngFor="let option of filterRegions | async" [value]="option.name">
<img style="vertical-align:middle;" [src]="'https://upload.wikimedia.org/wikipedia/commons/' + option.flag"
height="50" width="50" alt="country flag" />
<span> {{ option.name }}</span> |
<small>Population: {{ option.population}} </small>
<small>Area : {{ option.area }}</small>
</mat-option>
</mat-autocomplete>
</mat-form-field>
</section>
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
interface Country {
name: string;
flag: string;
area: number;
population: number;
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
countryCtrl = new FormControl();
filterRegions: Observable<any[]> | undefined;
data: Country[] = [];
constructor(
private http: HttpClient) {
this.http.get<Country[]>('./assets/data/countries.json')
.subscribe((res: Country[]) => {
this.data = res;
});
this.filterRegions = this.countryCtrl.valueChanges.pipe(
startWith(''),
map(region => region ? this.getRegions(region) : this.data.slice())
);
}
getRegions(name: any): any {
return this.data.filter((x: any) => x.name.toLocaleLowerCase().indexOf(name.toLocaleLowerCase()) > -1);
}
}
Conclusion
We have completed our Angular material autocomplete example tutorial. We also demonstrated how to add images or HTML elements in the material option. hope, you have got some idea.
Related Articles
- How to install Angular material ?
- How to implement Angular autocomplete in Angular
- How to implement Angular material dropdown | select .?