Topic: Autocomplete displayValue and manually set value
                  
                  Fiducial
                  free
                  asked 5 years ago
                
Hi,
I'm using the mdbautocomplete with a server side search. When user selects something, i want to keep the UserSelected object, and write the FullName in the field. So i used "displayValue" for that purpose. Template-driven form .html:
 <div class="md-form">
          <input #userInput="ngModel" type="text" class="completer-input form-control " [(ngModel)]="SearchText" [mdbAutoCompleter]="auto"
                 placeholder="Nom ou matricule" (focusout)="OnLeave()"/>
          <mdb-auto-completer #auto="mdbAutoCompleter" [displayValue]="displayFn" >
            <mdb-option *ngFor="let user of userList" [value]="user">
              <div class="d-flex flex-column">
                <span><strong>{{ user.FullName }}</strong></span>
                <span>{{ user.Societe }}</span>
              </div>
            </mdb-option>
          </mdb-auto-completer>
</div>
TS file:
 OnLeave() {
        if (this.userInput.value === '') {
          this.SelectedUser = null;
        }
        this.SearchText = this.SelectedUser;
      }
      displayFn(user): string {
        return user && user.FullName ? user.FullName : '';
      }
ngAfterViewInit(): void {
    this.userInput
      .valueChanges
      .pipe(debounceTime(300), filter(theNewValue => typeof theNewValue === 'string'))
      .subscribe(theNewValue => {
        this.searchUser(theNewValue);
      });
    this.userInput
      .valueChanges
      .pipe(filter(theNewValue => typeof theNewValue !== 'string'))
      .subscribe(theNewValue => {
        this.SelectedUser = theNewValue;        
      });
  }
With this, i can keep track of the latest selecteduser, and the actual search text. If the user change the search text, but does not select anyone, and leave the text, i would like to put back the name of the previous selected user (as a 'cancel search' would do)
But when i do: this.SearchText = this.SelectedUser; i get [Object object] in the field instead of the actual FullName, (displayValue function is not called)
What am i doing wrong?
Thanks!
                      
                      Arkadiusz Idzikowski
                      staff
                        answered 5 years ago
                    
In this case SearchText should be of type string and you try to overwrite it with object here:
this.SearchText = this.userStaticList[0];
and here:
this.SearchText = this.SelectedUser;
In your case it should look like this:
this.SearchText = this.userStaticList[0].FullName;
this.SearchText = this.SelectedUser.FullName;
If you don't use TSLint it is good idea to configure it in your IDE/Code editor, because it will automatically let you know about problems with types.
                      
                      Fiducial
                      free
                        answered 5 years ago
                    
Hi, Here are the request files with a simple static example: [HTML]:
<div class="md-form">
  <input #userInput2="ngModel" type="text" class="completer-input form-control " [(ngModel)]="SearchText" [mdbAutoCompleter]="auto2"
         placeholder="Nom ou matricule" (focusout)="OnLeave()"/>
  <mdb-auto-completer #auto2="mdbAutoCompleter" [displayValue]="displayFn"  >
    <mdb-option *ngFor="let user of userList" [value]="user">
      <div class="d-flex flex-column">
        <span><strong>{{ user.FullName }}</strong></span>
      </div>
    </mdb-option>
  </mdb-auto-completer>
</div>
[TS]
import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
import {debounceTime, filter} from 'rxjs/operators';
@Component({
  selector: 'app-test-mdb-autocomplete',
  templateUrl: './test-mdb-autocomplete.component.html',
  styleUrls: ['./test-mdb-autocomplete.component.css']
})
export class TestMdbAutocompleteComponent implements OnInit,AfterViewInit {
  constructor() {
  }
  userStaticList = [
    {FullName: 'Marine', ID: '1'},
    {FullName: 'Fred', ID: '2'},
    {FullName: 'Marinette', ID: '3'},
    {FullName: 'Marilou', ID: '4' }
    ];
  userList = [];
  @ViewChild('userInput2') private userInput2;
  SearchText = '';
  SelectedUser: null;
  ngOnInit(): void {
    //Render [object Object] instead of user.FullName (Marine) in the search field
    //displayFn not called
    this.SearchText = this.userStaticList[0];
  }
  ngAfterViewInit() {
    this.userInput2.valueChanges
      .pipe(debounceTime(300),
        filter(val => typeof val === 'string')
      ).subscribe(val => {
        this.userList = [];
        this.userStaticList.forEach(elem => {
          if (elem.FullName.toLowerCase().startsWith(val.toString().toLowerCase())) {
            this.userList.push(elem);
          }
        });
      }
    );
    this.userInput2
      .valueChanges
      .pipe(filter(theNewValue => typeof theNewValue !== 'string'))
      .subscribe(theNewValue => {
          this.SelectedUser = theNewValue;
        });
  }
  displayFn(user) {
    let nameOfUser= (user ? user.FullName : '');
    console.log('DisplayFn:'+user);
    console.log('DisplayFn returned value:'+nameOfUser);
    return nameOfUser;
  }
  OnLeave() {
    if (this.userInput2.value) {
      if (this.SelectedUser) {
        this.SearchText = this.SelectedUser;
      } else {
        this.SearchText = '';
      }
    }else
    {
      this.SelectedUser=null;
    }
  }
}
Thanks
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- ForumUser: Free
 - Premium support: No
 - Technology: MDB Angular
 - MDB Version: 9.0.1
 - Device: PC
 - Browser: Chromium
 - OS: WIndows
 - Provided sample code: No
 - Provided link: No
 
Arkadiusz Idzikowski staff commented 5 years ago
Can you prepare a simple example with static data and full html/ts code so we can reproduce that on our end?