Angular Autcomplete Text Box from API Array

87 Views Asked by At

I'm trying to figure out how to get a text box to populate with user's emails from an API call to the server.

select-users.component.html:

<input type="text"
    placeholder="Email Search"
    aria-label="Email"
    matInput
    [formControl]="myControl"
    [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
  <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
    {{option}}
  </mat-option>
</mat-autocomplete>

select-users.component.ts

interface User {
  email: string;
}

export class SelectUsersComponent implements OnInit {
  public userList: User[] = [];
  myControl = new FormControl();
  // options: string[] = ['[email protected]', '[email protected]', '[email protected]'];
  options: string[] = [];
  filteredOptions: Observable<string[]>;

  constructor(private gService: GService) { }

  ngOnInit(): void {
    this.userSearch().then();
    this.filteredOptions = this.myControl.valueChanges.pipe(
      startWith(''),
      map(value => this._filter(value))
    );
  }

  private _filter(value: string): string[]{
    const filterValue = value.toLowerCase();
    return this.options.filter(option => option.toLowerCase().includes(filterValue));
  }

  /**
   * Retrieve users from gService
   */
    public userSearch = async () => {
    const result = await this.gService.getUsers();
    this.userList = [];
    result?.list?.entries?.forEach(({ entry }) => {
      this.userList.push({
        email: entry.properties?.['cm:email']
      });
    });
    this.options = this.userList.map(User => User.email);
  };
}

Where the userSearch function is making a call to a separate gService.getUsers() function that returns an Alfresco-based set of users (this is the API call, which isn't really shown here in the TypeScript code), stores the User objects into the userList, and lastly stores all userList User.email's into the options array.

Now, my problem is that the return function in _filter doesn't return anything at all. I've done a series of tests and the options array populates just fine and the emails look appropriate in print-outs and logs, but the filter isn't sorting (or is dropping?) that array.

Additional oddity: if you take a look at the commented-out version of options, if you comment it back in and run the program you actually get results from _filter just as you would expect to.

So I'm kind of at a loss - am I storing the emails in the options array wrong?

1

There are 1 best solutions below

0
On

I resolved my issue. As it turned out, the array that was making it into the options array had a lot of gaps in it (I'm not sure why, honestly) in so much that it looked like the following:

['[email protected]', '[email protected]',,,'[email protected]',,'[email protected]']

So just out of curiosity I put some code to filter out the empty space in the array and shorten it to only include filled indexes:

var len = this.options.length;
    var i;
    for(i=0; i<len; i++){
      this.options[i] && this.options.push(this.options[i]);
    }
    this.options.splice(0, len);

It's not the cleanest way to do it as its just a simple iterator, but it actually made the program work as intended!

Hopefully this helps someone in the future.