Reputation: 391
I am using Angular 5 in a project and i get a typescript error:
ERROR TypeError: Cannot read property 'indexOf' of undefined
What my code is supposed to do is to update the template on input change like this:
The template:
<input #f (input)="filterResults(f.value)"/>
<div *ngIf="filteredCandidates.length">
<ul class="filtered-candidates-list">
<li *ngFor="let candidate of filteredCandidates">
{{ candidate.name }}
</li>
</ul>
</div>
And the component.ts:
private queryString: string;
private candidates: Candidate[] = []
private filteredCandidates: Candidate[] = [];
filterResults(queryString) {
this.candidatesService.filterCandidates().subscribe(candidates => this.candidates = candidates);
if (!queryString) {
return;
}
else {
this.candidates.filter(c => { c.name.indexOf(queryString) >= 0 });
}
}
I tried using the method .contains() on the c.name, and got the same result. The typeof candidate.name is still string, as expected, as well as the input which is also a string. However, it is like i can't use the string methods just due to typescript being incorporated.
Upvotes: 3
Views: 1135
Reputation: 136184
It seems like you're trying to perform filter operation on collection candidates
even though it haven't been retrieved from the API server yet. By looking at your UI, it doesn't look like you are peforming any remote filtering based on query string. In this case I'd recommend to retrieve the candidates
collection at the start and untill then make input
box disabled/readonly. So that will avoid unexpected error to happen.
HTML
<input #f (input)="filterResults(f.value)" [readonly]="candidates.length"/>
<div *ngIf="filteredCandidates.length">
<ul class="filtered-candidates-list">
<li *ngFor="let candidate of filteredCandidates">
{{ candidate.name }}
</li>
</ul>
</div>
Component
private queryString: string;
private candidates: Candidate[] = []
private filteredCandidates: Candidate[] = [];
getResults(){
this.candidatesService.filterCandidates().subscribe(
candidates => this.candidates = candidates || []
);
};
filterResults(queryString) {
if (!queryString) {
return;
}
else {
this.candidates.filter(c => { c.name && c.name.indexOf(queryString) >= 0 });
}
}
Upvotes: 1
Reputation: 391
What a foolish mistake. I had to do some error handling. In the database, one of the objects had no property name (undefined). So when the loop got there, the code broke. I have to handle errors better. Thank you all for suggestions though.
Upvotes: 0
Reputation: 10313
If c.name is not defined in some cases, you could do the check like this:
this.candidates.filter(c => {
return c.name !== null && c.name.indexOf(queryString) >= 0
});
Here, !== null will check for both null and undefined values.
Upvotes: 1