Topic: Multiple mdb-auto-completer in a single form
                  
                  JeroenVunderink
                  priority
                  asked 5 years ago
                
Expected behavior I expect that since I use different functions for the two mdb-auto-completer they work completely independent from each other
Actual behavior Putting each mdb-auto-completer separtely on a page they work. Putting 2 beneath each other it doesn't. Only the first mdb-auto-completer works properly and and after select it fills in the seconds one as well with the first one value and clog errors starting with: ERROR TypeError: this.listenFunc is not a function at MdbAutoCompleterDirective._hide (ng-uikit-pro-standard.js:12277) at SafeSubscriber._next (ng-uikit-pro-standard.js:12311)
Resources (screenshots, code snippets etc.)
The TS File:
import { Component, OnInit } from '@angular/core';
import { Subject, Observable } from 'rxjs';
import { startWith, switchMap, debounceTime, map } from 'rxjs/operators';
@Component({
  selector: 'app-autocomplete',
  templateUrl: './autocomplete.component.html',
  styleUrls: ['./autocomplete.component.scss']
})
export class AutocompleteComponent implements OnInit {
  searchText = new Subject();
  results: Observable<string[]>;
  data: any = [
    'red',
    'green',
    'blue',
    'cyan',
    'magenta',
    'yellow',
    'black',
  ];
  searchText2 = new Subject();
  results2: Observable<string[]>;
  data2: any = [
    'audi',
    'citroen',
    'crysler',
    'fiat',
    'ford',
    'peugeot',
    'volvo'
  ];
  ngOnInit() {
    this.results = this.searchText.pipe(
      startWith(''),
      map((value: string) => this.filter(value))
    );
    this.results2 = this.searchText2.pipe(
      startWith(''),
      map((value: string) => this.filter2(value))
    );
  }
  filter(value: string): string[] {
    const filterValue = value.toLowerCase();
    return this.data.filter((item: string) => item.toLowerCase().includes(filterValue));
  }
  filter2(value: string): string[] {
    const filterValue = value.toLowerCase();
    return this.data2.filter((item: string) => item.toLowerCase().includes(filterValue));
  }
}
The HTML File:
<p>autocomplete works!</p>
<div class="md-form">
  <input
    type="text"
    class="completer-input form-control mdb-autocomplete"
    [ngModel]="searchText | async"
    (ngModelChange)="searchText.next($event)"
    [mdbAutoCompleter]="auto"
    placeholder="Choose your color"
  />
  <mdb-auto-completer #auto="mdbAutoCompleter" textNoResults="I have found no results :(">
    <mdb-option *ngFor="let option of results | async" [value]="option">
      {{ option }}
    </mdb-option>
  </mdb-auto-completer>
</div>
<div class="md-form">
  <input
    type="text"
    class="completer-input form-control mdb-autocomplete"
    [ngModel]="searchText2 | async"
    (ngModelChange)="searchText2.next($event)"
    [mdbAutoCompleter]="auto"
    placeholder="Choose your brand"
  />
  <mdb-auto-completer #auto="mdbAutoCompleter" textNoResults="I have found no results :(">
    <mdb-option *ngFor="let car of results2 | async" [value]="car">
      {{ option }}
    </mdb-option>
  </mdb-auto-completer>
</div>
                
                  
                      
                      JeroenVunderink
                      priority
                        answered 5 years ago
                    
Thank you so much. I didn't exactly know/understand how the binding worked.
For other users that encounter the same issue I have put the updated code below that works.
The TS file:
import { Component, OnInit } from '@angular/core';
import { Subject, Observable } from 'rxjs';
import { startWith, map } from 'rxjs/operators';
@Component({
  selector: 'app-autocomplete',
  templateUrl: './autocomplete.component.html',
  styleUrls: ['./autocomplete.component.scss']
})
export class AutocompleteComponent implements OnInit {
  searchText = new Subject();
  results: Observable<string[]>;
  data: any = [
    'red',
    'green',
    'blue',
    'cyan',
    'magenta',
    'yellow',
    'black',
  ];
  searchText2 = new Subject();
  results2: Observable<string[]>;
  data2: any = [
    'audi',
    'citroen',
    'crysler',
    'fiat',
    'ford',
    'peugeot',
    'volvo'
  ];
  ngOnInit() {
    this.results = this.searchText.pipe(
      startWith(''),
      map((value: string) => this.filter(value))
    );
    this.results2 = this.searchText2.pipe(
      startWith(''),
      map((value: string) => this.filter2(value))
    );
  }
  filter(value: string): string[] {
    const filterValue = value.toLowerCase();
    return this.data.filter((item: string) => item.toLowerCase().includes(filterValue));
  }
  filter2(value: string): string[] {
    const filterValue = value.toLowerCase();
    return this.data2.filter((item: string) => item.toLowerCase().includes(filterValue));
  }
}
The HTML file:
<p>autocomplete works!</p>
<div class="md-form">
  <input
    type="text"
    class="completer-input form-control mdb-autocomplete"
    [ngModel]="searchText | async"
    (ngModelChange)="searchText.next($event)"
    [mdbAutoCompleter]="color"
    placeholder="Choose your color"
  />
  <mdb-auto-completer #color="mdbAutoCompleter" textNoResults="I have found no results :(">
    <mdb-option *ngFor="let option of results | async" [value]="option">
      {{ option }}
    </mdb-option>
  </mdb-auto-completer>
</div>
<div class="md-form">
  <input
    type="text"
    class="completer-input form-control mdb-autocomplete"
    [ngModel]="searchText2 | async"
    (ngModelChange)="searchText2.next($event)"
    [mdbAutoCompleter]="car"
    placeholder="Choose your brand"
  />
  <mdb-auto-completer #car="mdbAutoCompleter" textNoResults="I have found no results :(">
    <mdb-option *ngFor="let car of results2 | async" [value]="car">
      {{ car }}
    </mdb-option>
  </mdb-auto-completer>
</div>
                    
                      
                      
                      Arkadiusz Idzikowski
                      staff
                        answered 5 years ago
                    
That's because you used the same id #auto for both components. This value should be unique. When you set new, unique value for second autocomplete, you also need to update it here: [mdbAutoCompleter]="auto2"
metalor-it pro commented 4 years ago
Hello, How to manage a dynamic form using a static # ? imagin I have the Autocompleter #supplier for the first article. I if I hadd a second article at runtime the Autocompleter is also #supplier. Is there a way to make it dynamic ? Thank you
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Resolved
- ForumUser: Priority
 - Premium support: Yes
 - Technology: MDB Angular
 - MDB Version: 9.1.0
 - Device: MacAir
 - Browser: Chrome
 - OS: MacOS
 - Provided sample code: No
 - Provided link: No