sourabh kumar
sourabh kumar

Reputation: 671

matches.slice is not a function ng2-bootstrap typeahead

I am trying to use ng2-bootstrap Typeahead with REST backend.

HTTP Response

[{
    "productDescription": "MAIL MKTG NIKLES HIGHLIGHT TUBE",
    "productNumber": "10667"
}, {
    "productDescription": "SIGHT GLASSES/VAC BREAKER BR 15MM BSP",
    "productNumber": "100436"
}, {
    "productDescription": "SIGHT GLASSES/VAC BREAKER BR 15MM BSP",
    "productNumber": "100438"
}]

app.component.ts

import {TYPEAHEAD_DIRECTIVES} from 'ng2-bootstrap/ng2-bootstrap';

@Component({
  selector: 'my-app',
  directives: [TYPEAHEAD_DIRECTIVES, CORE_DIRECTIVES, FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES],
  templateUrl: './app/typeahead-demo.html',
  providers: [HTTP_PROVIDERS, FreightService]
})
export class TypeaheadDemoComponent {
  public stateCtrl:FormControl = new FormControl();
  public myForm:FormGroup= new FormGroup({
    state: this.stateCtrl
  });

  public selected:string = '';
  public dataSource:Observable<any>;
  public asyncSelected:string = '';
  public typeaheadLoading:boolean = false;
  public typeaheadNoResults:boolean = false;

  public constructor(private freightService: FreightService) {
    this.dataSource = Observable.create((observer:any) => {
      observer.next(this.asyncSelected);
    }).mergeMap(() => this.getStatesAsObservable());
  }

  public getStatesAsObservable():Observable<any> {

    return Observable.of(
        this.freightService
            .getMatchingProduct(this.asyncSelected).map(error => console.log(error))
    );
  }
}

freight.service.ts

I am using mocky.io to fake REST response.

import { Injectable } from '@angular/core';
import { Headers, Http, Response, URLSearchParams } from '@angular/http';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class FreightService {

    constructor(private http: Http) {

    }

    getMatchingProduct(productKeyword: string): Observable <string> {

        return this.http.get("http://www.mocky.io/v2/57b6988e0f0000b8020b7996")
            .map(this.extractData);
    }

    private extractData(res: Response) {
        let body = res.json();
        return body.data || { };
    }
}

typeahead-demo.html

  <h4>Asynchronous results</h4>
  <pre class="card card-block card-header">Model: {{myForm.value.state | json}}</pre>
  <form [formGroup]="myForm">
    <input formControlName="state"
         [(ngModel)]="asyncSelected"
         [typeahead]="dataSource"
         (typeaheadLoading)="changeTypeaheadLoading($event)"
         (typeaheadNoResults)="changeTypeaheadNoResults($event)"
         (typeaheadOnSelect)="typeaheadOnSelect($event)"
         [typeaheadOptionsLimit]="7"
         [typeaheadOptionField]="'productDescription'"
         placeholder="Locations loaded with timeout"
         class="form-control">
  </form>

I am really stuck with error "TypeError: matches.slice is not a function"

Upvotes: 2

Views: 1648

Answers (2)

sourabh kumar
sourabh kumar

Reputation: 671

Below worked!!

app.component.ts

  public constructor(private freightService: FreightService) {
    this.dataSource = Observable.create((observer:any) => {
       this.freightService.getMatchingProduct(this.asyncSelected)
       .subscribe((result: any) => {
         observer.next(result);
       })
    });
  }

freight.service.ts

@Injectable()
export class FreightService {

    constructor(private http: Http) {

    }

    getMatchingProduct(productKeyword: string): Observable <any> {

        return this.http.get("app/test").map(this.extractData);
    }

    private extractData(res: Response) {
        let body = res.json();
        return body || { };
    }
}

Upvotes: 1

Adrian F&#226;ciu
Adrian F&#226;ciu

Reputation: 12562

It looks like you're mapping all the result to undefined with this line: .map(error => console.log(error)). It will not catch errors, it will simply map all the values to the result of console.log() which will be undefined.

Also the result from getMatchingProduct should be an Observable so there is no need for Observable.of.

If you want to handle errors you can try the .catch method.

Upvotes: 1

Related Questions