0

Hi I am developing web application in Angular JS 5. I am trying to complete auto search feature. I am able to make it work with static values. Now I am trying to get data from making API call. Below is my code.

import { Component } from '@angular/core';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { TypeaheadMatch } from 'ngx-bootstrap/typeahead';


    @Component({
      selector: 'demo-typeahead-async',
      templateUrl: './async.html'
    })
    export class DemoTypeaheadAsyncComponent {
      asyncSelected: string;
      typeaheadLoading: boolean;
      typeaheadNoResults: boolean;
      dataSource: Observable<any>;
      statesComplex: any[] = [
        { id: 1, name: 'Alabama', region: 'South' },
        { id: 2, name: 'Alaska', region: 'West' },
        {
          id: 3,
          name: 'Arizona',
          region: 'West'
        },
        { id: 4, name: 'Arkansas', region: 'South' },
        { id: 5, name: 'California', region: 'West' },
        { id: 6, name: 'Colorado', region: 'West' }
    ];

      constructor() {
        this.dataSource = Observable.create((observer: any) => {
          // Runs on every search
          observer.next(this.asyncSelected);
        }).mergeMap((token: string) => this.getStatesAsObservable(token));
      }

      getStatesAsObservable(token: string): Observable<any> {
        let query = new RegExp(token, 'ig');

        return Observable.of(
          this.statesComplex.filter((state: any) => {
            return query.test(state.name);
          })
        );
      }

      changeTypeaheadLoading(e: boolean): void {
        this.typeaheadLoading = e;
      }

      changeTypeaheadNoResults(e: boolean): void {
        this.typeaheadNoResults = e;
      }

      typeaheadOnSelect(e: TypeaheadMatch): void {
        console.log('Selected value: ', e.value);
      }
    }

In the above code, I am playing through this.statesComplex(Hard coded data). Below is my html code.

<pre class="card card-block card-header">Model: {{asyncSelected | json}}</pre>
  <input [(ngModel)]="asyncSelected"
         [typeahead]="dataSource"
         (typeaheadLoading)="changeTypeaheadLoading($event)"
         (typeaheadNoResults)="changeTypeaheadNoResults($event)"
         (typeaheadOnSelect)="typeaheadOnSelect($event)"
         [typeaheadOptionsLimit]="7"
         typeaheadOptionField="name"
         placeholder="Locations loaded with timeout"
         class="form-control">
  <div *ngIf="typeaheadLoading===true">Loading</div>
  <div *ngIf="typeaheadNoResults===true">&#10060; No Results Found</div>

I have created service to call API as below.

this.useronboardService.searchUsers(query).subscribe(results => this.filterUsername(query, results), error => this.onUsersSearchDataLoadFailed(error));

I tried as below. Below code did not work for me.

 getStatesAsObservable(token: string): Observable<any> {
        let query = new RegExp(token, '');
        return Observable.of(
            this.useronboardService.searchUsers(token).subscribe(
                 result => result.filter((user: any) => {
                   return query.test(user.userName),
                        error => console.log(error)
                }))
    );

I want to use above service data instead of this.statesComplex. My service returns array which hold properties id and username. can someone help me to make this work? Thank you.

2
  • You can subscribe to valueChanges Observable of the formControl, add some debounceTime so that it doesn't make a lot of backend calls. And make you backend calls after the debounceTime in the subscribe. Commented Feb 23, 2018 at 3:41
  • Thanks pavan. Can you share me few links to get it done. Thank you Commented Feb 23, 2018 at 4:02

1 Answer 1

1

this.useronboardService.searchUsers(token) is already an observable, so you don't need to wrap it in Observable.of(...). Just map the result to filtered values.

getStatesAsObservable(token: string): Observable<any> {
    let query = new RegExp(token, '');
    return this.useronboardService.searchUsers(token)
        .map(result => result.filter((user: any) => query.test(user.userName)));
}
Sign up to request clarification or add additional context in comments.

2 Comments

You're welcome. Also you can simplify your constructor, using Observable.of(this.asyncSelected) instead of Observable.create(...).
Hi David. I found one error in above code. If there are two matching records exists as we enter string for search, In ui we will get only one result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.