Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material autocomplete From API

I try to use auto complete from api but it not work. its work only without api.

this is my Component TS: inside there, There is a callback method with the data from the api (onGetTaxList)

import { Component, OnInit } from '@angular/core';
import { UsersService } from '../../../../core/services/users.service';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

@Component({
  selector: 'app-create-process-modal',
  templateUrl: './create-process-modal.component.html',
  styleUrls: ['./create-process-modal.component.sass']
})
export class CreateProcessComponent implements OnInit {
  myControl = new FormControl();
  options = [
    { name: 'One' },
    { name: 'Two' },
    { name: 'Tree' },
  ];
  filteredOptions: Observable<any>;


  constructor(private service: UsersService) { }

  ngOnInit() {
    this.service.createNewProcess((data) => this.onGetTaxList(data));
    this.filteredOptions = this.myControl.valueChanges
      .pipe(
        startWith(''),
        map(value => this._filter(value))
      );
  }

  onGetTaxList(data) {
    console.log(data);
  }
  private _filter(value: string) {
    const filterValue = value.toLowerCase();

    return this.options.filter(option => option.name.toLowerCase().includes(filterValue));
  }
}

Component html:

<div class="formContainer">
    <h2 style="text-align: right">New Process</h2>
    <mat-form-field style="text-align: right">
        <input type="text" placeholder="Start Typing..." matInput [formControl]="myControl" [matAutocomplete]="auto">
        <mat-autocomplete #auto="matAutocomplete">
                <mat-option *ngFor="let option of filteredOptions | async" [value]="option.name">
                  {{option.name}}
                </mat-option>
              </mat-autocomplete>
    </mat-form-field>

</div>

In this state its work with the object

options = [
        { name: 'One' },
        { name: 'Two' },
        { name: 'Tree' },
      ];

and now i want its work from the data api:

0: {companyName: "ziro", cid: "524023240", partners: Array(4)}
1: {companyName: "plus", cid: "524023240", partners: Array(2)}

and i need the auto complete filter the companyName. Thanks.

like image 995
Baruch Mashasha Avatar asked Sep 09 '19 10:09

Baruch Mashasha


People also ask

How do I use angular material autocomplete?

Simple autocompleteStart by creating the autocomplete panel and the options displayed inside it. Each option should be defined by a mat-option tag. Set each option's value property to whatever you'd like the value of the text input to be when that option is selected.

What is Matautocomplete in angular?

The <mat-autocomplete>, an Angular Directive, is used as a special input control with an inbuilt dropdown to show all possible matches to a custom query. This control acts as a real-time suggestion box as soon as the user types in the input area.

How do you clear mat autocomplete when no option is selected from autocomplete dropdown?

You can remove the formControl-binding from your input and when you select an option you set that id to your form. You are already calling such a function (onSelectionChange)="onEnteredAccount(accountOption)" in which you can do that.

What is autocomplete in Angular 4?

This Angular post is compatible with Angular 4 upto latest versions, Angular 7, Angular 8, Angular 9, Angular 10, Angular 11, Angular 12 and Angular 13 Autocomplete or Typeahead search component is used to get user-specified small set of items which are fetch based on term entered from a huge database list data.

What determines whether the autocomplete panel should be visible?

Whether the autocomplete panel should be visible, depending on option length. The autocomplete panel to be attached to this trigger. Whether the autocomplete is disabled. When disabled, the element will act as a regular input and the user won't be able to open the panel.

How do I add autocomplete to a form?

The autocomplete is a normal text input enhanced by a panel of suggested options. Start by adding a regular matInput to your template. Let's assume you're using the formControl directive from ReactiveFormsModule to track the value of the input.

How do I configure the autocomplete panel in mat?

Whether the first option should be highlighted when the autocomplete panel is opened. Can be configured globally through the MAT_AUTOCOMPLETE_DEFAULT_OPTIONS token. Takes classes set on the host mat-autocomplete element and applies them to the panel inside the overlay container to allow for easy styling. Whether ripples are disabled.


2 Answers

Component:

  constructor(private service: Service) { 
  this.filteredOptions = this.myControl.valueChanges
        .pipe(
          startWith(''),
          debounceTime(400),
          distinctUntilChanged(),
          switchMap(val => {
            return this.filter(val || '')
          })       
        );
  }

  // filter and return the values
 filter(val: string): Observable<any[]> {
    // call the service which makes the http-request
    return this.service.getData()
     .pipe(
       map(response => response.filter(option => { 
         return option.name.toLowerCase().indexOf(val.toLowerCase()) === 0
       }))
     )
   }  
}

Service:

opts = [];

getData() {
  return this.opts.length ?
    of(this.opts) :
    this.http.get<any>('https://jsonplaceholder.typicode.com/users').pipe(tap(data => this.opts = data))
}

For check full demo check this link Stackblitz

like image 71
Savaj Patel Avatar answered Oct 21 '22 23:10

Savaj Patel


I see no attempt to even get the data from Api, so first of all you should add that. Then you are trying to filter by name, which does not exist in your data, you want to filter by companyName, then use that. All in all, change your code to:

this.filteredOptions = this.myControl.valueChanges
  .pipe(
    startWith(''),
    switchMap(value => this._filter(value))
  );

And the function to filter and getting the data from api:

private _filter(value: string) {
  const filterValue = value.toLowerCase();
  // add your service function here
  return this.service.getData().pipe(
    filter(data => !!data),
    map((data) => {
      return data.filter(option => option.companyName.toLowerCase().includes(value))
    })
  )
}

DEMO: StackBlitz

like image 22
AT82 Avatar answered Oct 21 '22 21:10

AT82