i am new in angular 12, I created a search input and a list of static data, and I decided to write a pipe to filter the data when I search something, So after I added the pipe inside the ngFor I got an error that says : Error: src/app/template/ui/pages/courses/courses.component.html:23:78 - error TS2339: Property 'query' does not exist on type 'CoursesComponent'.
23 <div class="col-12 col-lg-4" *ngFor="let item of data | searchFilter: query ">
~~~~~
src/app/template/ui/pages/courses/courses.component.ts:13:16
13 templateUrl: './courses.component.html',
~~~~~~~~~~~~~~~~~~~~~~~~~~
The error occurs in the template of component CoursesComponent.
So I checked the existing answers here but none speaking about Pipe and NgModel so here's my pipe:
import { Pipe, PipeTransform } from "@angular/core";
@Pipe({
name: 'searchFilterPipe'
})
export class SearchFilterPipe implements PipeTransform {
transform(value: any, args?: any): any {
if(!value) return null;
if(!args) return value;
args = args.toLowerCase();
return value.filter(function(data: any){
return JSON.stringify(data).toLowerCase().includes(args);
});
}
}
Here my view:
<form action="">
<div class="input-group mb-4 border rounded-pill p-1">
<input id="searchInputtwo" type="search" [(ngModel)]="query" placeholder="What're you searching for?" aria-describedby="button-addon3" class="form-control bg-none border-0" >
<div class="input-group-append border-0">
<button id="button-addon3" type="submit" class="btn btn-link text-dark"><i class="fa fa-search"></i></button>
</div>
</div>
</form>
</div>
</div>
<div class="row" id="lessonList">
<div class="col-12 col-lg-4" *ngFor="let item of data | searchFilter: query ">
<div class="card mb-4 mb-lg-0 border-secondary shadow">
<img src="{{item.image}}" alt="Animations CSS modernes" class="card-img-top">
<div class="card-body">
<h5 class="card-title">{{ item.title }}</h5>
<p class="card-text">{{item.text}}</p>
<a href="courses/details/{{item.id}}" class="btn btn-info btn--start ">Démarrer l'apprentissage</a>
</div>
</div>
</div>
Here my Ts file:
import { Component, Input, OnInit, NgModule } from '@angular/core';
import { chapterModel } from 'src/app/core/models/chapter.model';
import { competencesModel } from
'src/app/core/models/competences.model';
import { CourseModel } from 'src/app/core/models/course.model';
import { preriquisiteModel } from
'src/app/core/models/preriquisite.model';
import { teacherModel } from 'src/app/core/models/teacher.model';
import { SearchService } from 'src/app/core/services/search.service';
@Component({
selector: 'app-courses',
templateUrl: './courses.component.html',
styleUrls: ['./courses.component.scss']
})
export class CoursesComponent implements OnInit {
public searchFilter: any = '';
public data:CourseModel[];
constructor(private searchService: SearchService) {
this.data = [
new CourseModel(1,"Créez des animations CSS","Vous allez plonger dans le monde des animations CSS pour donner vie à vos pages web !",
[new chapterModel(1,"coo","text")],false,
[new preriquisiteModel(2,"Programmation JavaScript","Programmation JavaScript","Learn Java Script !")],
[ new competencesModel("Savoir Faire des animations")], [ new teacherModel(52,"Laura DuFont") ],
"assets/images/lessons/css.jpeg"),
new CourseModel(2,"Programmer avec JavaScript","Ce cours est conçu pour vous enseigner les bases du langage de programmation JavaScript.",
[new chapterModel(1,"coo","text")],false,
[new preriquisiteModel(1,"Programmation html/css","Programmation html/css","Learn Html/Css !")],
[ new competencesModel("Savoir le language Java Script")], [ new teacherModel(53,"Will Alexander") ],
"assets/images/lessons/js.jpeg"),
new CourseModel(3,"Les fondamentaux de Swift","Découvrez le développement iOS et réalisez des applications taillées pour l'iPhone et l'iPad !",
[new chapterModel(1,"coo","text")],false,
[new preriquisiteModel(2,"Programmation ","Programmation ","Learn Swift !")],
[ new competencesModel("Savoir programmer pour Iphone et Ipad")], [ new teacherModel(54,"Jamie Sutherland") ],
"assets/images/lessons/swift.jpeg"),
];
}
ngOnInit(): void {
}
searchForm(){
this.searchService.searchAndFilterCourses(this.searchFilter);
console.log(this.searchFilter);
}
}
I took this code from a tutorial of Angular 9 but I don't know if my angular 12 needs a different syntax or not.
My goal is to find a solution for this problem and make the solution available for all possible future victims of this error.
When you're using [(ngModel)]
you are binding the value of the input field to a property inside your component's TS file. In your case you have [(ngModel)]="query"
which means it's expecting the property query
to exist.
But in your TS file you only have searchFilter
and data
defined. Add public query = '';
and it should no longer give you the error.
Also, you shouldn't need to setup a pipe unless you're planning to use this filtering logic many times across your app. If it's only happening in this component, you should keep the filtering logic in the component's TS file.