I'm new to observables and experimenting with an basic autocomplete variation of Christoph Burgdorf's Observables in Angular2 blog. Running this code produces:
EXCEPTION: TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined
after issuing the REST get call in ingredientservice...rawsearch. The alert also pops with an [object Object] message. I've verified the endpoint is running fine.
Any recommendations on how to debug this would be greatly appreciated.
ingredientservice.ts waits for a change on a text string, debounces it and performs a REST call to get autocomplete matches from an endpoint.
import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';
@Injectable()
export class IngredientService {
endpoint_url: String = "http://localhost:5000/ingredient/";
results: Observable<Array<string>>;
constructor(private http: Http) { }
search(terms: Observable<string>, debounceDuration = 400) {
return terms.debounceTime(debounceDuration)
.distinctUntilChanged()
.switchMap(term => this.rawSearch(term));
}
getData: Object[];
rawSearch(term: string) {
console.log(term);
this.http.get(this.endpoint_url + term)
.subscribe(
res => {
this.getData = res.json();
console.log(this.getData);
return this.getData;
},
error => alert(error));
}
}
for completeness I have included the component ingredientsearch.ts
import {Component} from 'angular2/core';
import {Control} from 'angular2/common';
import {IngredientService} from './ingredientservice';
import {Observable} from 'rxjs/Observable';
@Component({
selector: 'ingredient-search',
template: `
<div>
<h2>Ingredient Search</h2>
<input type="text" [ngFormControl]="term"/>
<ul>
<li *ngFor="#item of items | async">{{item}}</li>
</ul>
</div>
`,
providers: [IngredientService]
})
export class IngredientSearch {
items: Observable<Array<string>>;
term = new Control();
constructor(private ingredientService: IngredientService) {
console.log("About to call service");
this.items = ingredientService.search(this.term.valueChanges);
}
}
Updated code snippet with recommended fix.
rawSearch(term: string) {
this.getData = ([]);
this.http.get(this.endpoint_url + term)
.subscribe(
res => {
this.getData = res.json();
console.log(this.getData);
return this.getData;
},
error => {
alert(error);
});
return this.getData;
}
Items is undefined when the view is bound - before the service returns. Initialize items to an empty array. Or use an Observable wrapper and the async operator in your template.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With