matches.slice不是函数ng2-bootstrap typeahead

时间:2016-08-19 06:00:06

标签: angular rxjs typeahead ng2-bootstrap

我正在尝试使用带有REST后端的ng2-bootstrap Typeahead。

HTTP响应

[{
    "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

我正在使用mocky.io伪造REST响应。

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 || { };
    }
}

预输入-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>

我真的遇到错误&#34; TypeError:matches.slice不是函数&#34;

2 个答案:

答案 0 :(得分:1)

看起来您将所有结果映射到未定义的行:.map(error => console.log(error))。它不会捕获错误,它只会将所有值映射到console.log()的结果,这将是未定义的。

getMatchingProduct的结果也应该是Observable,因此不需要Observable.of

如果您想处理错误,可以尝试使用.catch方法。

答案 1 :(得分:1)

以下工作!!

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 || { };
    }
}