Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 6: ERROR TypeError: el.toLowerCase is not a function

I am creating a simple filter pipe in my app, here is what I have.

filter component:

import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({
      name: 'dataFilter'
    })
    export class DataFilterPipe implements PipeTransform {
    
      transform(value: any[], input: string) {
        if (input) {
            input = input.toLowerCase();
            return value.filter(function (el: any[]) {
                return el.toLowerCase().indexOf(input) > -1;
            });
        }
        return value;
    }
    
    }

here is componet.html

<div class="card movies-list" id="movies-list">
  <div class="card-header movies-list_header">
    <h1>Content:  <small>Best movies of 2010's</small></h1>
  </div>
  <div class="card-body">
    <div class="row movies-list_filter">
      <div class="col-md-2">Filter By</div>
      <div class="col-md-4">
        <input type='text' [(ngModel)]="listFilter">
      </div>
    </div>
    <div class="row">
      <div class="col-md-6">
        <h1>filterdbY: {{listFilter}}</h1>
      </div>
    </div>
    <table class="table table-striped table-responsive">
      <thead>
        <tr class="movies-list_tbheader">
          <td></td>
          <th>Title</th>
          <th>Realease</th>
          <th>Rating</th>
          <th>Description</th>
        </tr>
      </thead>
      <tbody>
        <tr class="movies-list_data" *ngFor="let movie of movies | dataFilter:listFilter">
          <td>
            <img *ngIf="movie.poster_path" class="thumbnail" src="http://image.tmdb.org/t/p/w500/{{movie.poster_path}}">
          </td>
          <td>{{ movie.title }}</td>
          <td>{{ movie.release_date }}</td>
          <td>{{movie.vote_average}}</td>
          <td>{{movie.overview}}</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

and in component.ts I have declared the variable listFilter like this:

export class MoviesComponent implements OnInit {
  listFilter = '';

-----------
}

when I run my app and try to seach some text I get the following error

ERROR TypeError: el.toLowerCase is not a function

what is wrong with my code? any help will be apreciated

like image 682
The Dead Man Avatar asked Jul 24 '18 23:07

The Dead Man


1 Answers

It is not considered "best practice" to use a pipe to filter data. Rather, do it in your component. For example:

// Local filter
performFilter(filterBy: string): IMovie[] {
    if (filterBy) {
        filterBy = filterBy.toLocaleLowerCase();
        return this.movies.filter((movie: IMovie) =>
            movie.title.toLocaleLowerCase().indexOf(filterBy) !== -1);
    } else {
        return this.movies;
    }
}

I have a detailed blog post about this here: https://blogs.msmvps.com/deborahk/filtering-in-angular/

It details why a pipe should not be used to filter and several different techniques for performing the above filter operation.

BTW ... this code really looks familiar. :-) This is the code from one of my OLD Angular v2 talks ... before we were notified by the team that using pipes in this way was not recommended.

Oh ... and I looked at the link you provided as a comment in the other answer (Which has since been deleted) and the code is NOT the same as you posted above. Here is the "working" code from your link:

  transform(value: IProduct[], filterBy: string): IProduct[] {
    filterBy = filterBy ? filterBy.toLocaleLowerCase() : null;
    return filterBy ? value.filter((product: IProduct) =>
        product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1) : value;
}

Here is the code from above:

  transform(value: any[], input: string) {
    if (input) {
        input = input.toLowerCase();
        return value.filter(function (el: any[]) {   // <---- data type!
            return el.toLowerCase().indexOf(input) > -1;
        });
    }
    return value;
}

Notice the data type passed to the filter function is any[]. It should just be any.

like image 100
DeborahK Avatar answered Oct 13 '22 09:10

DeborahK