Angular 10|9 Material Autocomplete Example with Remote/ Server Side Results

In the Angular Material tutorial, we’re going to discuss how to create a Material Autocomplete showing suggestion results from a remote server by using the mat-autocomplete component in the Angular 10/9/8/7/6/5/4 application.

This Angular post is compatible with Angular 4 upto latest versions, Angular 7, Angular 8, Angular 9, Angular 10, Angular 11 & Angular 12

We have already discussed the basic usage and implementation of Angular Material Autocomplete Component in an Angular Application in our previous post here.

Autocomplete is a very popular behaviour used in many applications to ease user form filling experience by providing some already built strings to fast data entry. Autocomplete is very similar to Input fields with addition to some Items showing up when the user focuses on that Input.

Sometimes we may need to show some results from the server-side as per a request made by the user. For example, there are two fields for State and City. A user will first select a State, then City list will load in other Input from the server-side according to state selected, as we may have thousands of cities from 12-15 states Right?

In this post, we will add Angular Autocomplete with the Debounce feature which will fetch results from server/API response. Here we will also use the HttpClient service of Angular to make a Get request to IMDB movies API for demonstration.

You can check my previous post to know more about adding Angular Material to the Angular project.

Autocomplete with server-side responses will also use the debounceTime method of Rxjs for optimized API calls for results.

 

Implement Server Side Autocomplete

Let’s add HttpClientModule and some other Angular material Modules which will be used in our demo.

Open App’s main module file app.module.ts then replace the below code.

//app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatInputModule } from '@angular/material/input';

import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule,
    MatInputModule,
    MatAutocompleteModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

To make server HTTP calls add HttpClientModule, for autocomplete import MatInputModule & MatAutocompleteModule.

We have FormsModule with ReactiveFormsModule so that we can easily bind RxJS debounceTime and also get the input value.

Add Autocomplete template

In app.component.html file replace below template to show Input Field with Autocomplete.

<div>

  <mat-form-field>
    <input matInput placeholder="Search" aria-label="State" [matAutocomplete]="auto" [formControl]="searchMoviesCtrl">
    <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
      <mat-option *ngIf="isLoading" class="is-loading">Loading...</mat-option>
      <ng-container *ngIf="!isLoading">
        <mat-option *ngFor="let movie of filteredMovies" [value]="movie.Title">
          <span><b>{{movie.Title}}</b> ({{movie.Year}})</span>
        </mat-option>
      </ng-container>
    </mat-autocomplete>
  </mat-form-field>

  <br>

<ng-container *ngIf="errorMsg; else elseTemplate">
  {{errorMsg}}
</ng-container>
<ng-template #elseTemplate>
  <h5>Selected Value: {{searchMoviesCtrl.value}}</h5>
</ng-template>

</div>

 

In app.component.ts file replace following code to make server calls to populate Autocomplete results using OMDB free API.

//app.component.ts
import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { HttpClient } from '@angular/common/http';

import { debounceTime, tap, switchMap, finalize } from 'rxjs/operators';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  searchMoviesCtrl = new FormControl();
  filteredMovies: any;
  isLoading = false;
  errorMsg: string;

  constructor(
    private http: HttpClient
  ) { }

  ngOnInit() {
    this.searchMoviesCtrl.valueChanges
      .pipe(
        debounceTime(500),
        tap(() => {
          this.errorMsg = "";
          this.filteredMovies = [];
          this.isLoading = true;
        }),
        switchMap(value => this.http.get("http://www.omdbapi.com/?apikey=[YOUR_KEY_HERE]=" + value)
          .pipe(
            finalize(() => {
              this.isLoading = false
            }),
          )
        )
      )
      .subscribe(data => {
        if (data['Search'] == undefined) {
          this.errorMsg = data['Error'];
          this.filteredMovies = [];
        } else {
          this.errorMsg = "";
          this.filteredMovies = data['Search'];
        }

        console.log(this.filteredMovies);
      });
  }
}

 

The debounceTime checks if the keypress interval is less than the time provided, then cancels the further events.

The tap and finalize operators are used to handling events before the server call and after response.

The switchMap is most similar to mergeMap but it is used here as it cancels the previous request event if the response is not received yet. But mergeMap waits for a previous response then make the next call so this behaviour is not required here.

Check Updated for Angular Material 12 Autocomplete with HTTP API Remote Search Results

 

Also check: How to add Angular Material Loaders and Spinners in Angular App

That’s it now you have a working Angular Material Autocomplete fetching server-side responses as user types in having RxJS DebounceTime which will only hit API HTTP call when the user stops typing.

 

12 Replies to “Angular 10|9 Material Autocomplete Example with Remote/ Server Side Results

  1. This tutorial is exactly what I was looking for but the api url needs to be updated to accept the search parameter so you can see the results that get returned, as is it will fail and not work.
    Here is the code that worked for me:
    switchMap(value => this.http.get(“http://www.omdbapi.com/?s=” + value +“&apikey=YOURAPIKEY”)
    Thanks for this tutorial, it was very useful!

Leave a Reply

Your email address will not be published. Required fields are marked *