[英]How to Filter Data coming from Firestore Database
I want to implement this filtering on my code, but I have an issue in implementing it.我想在我的代码上实现这个过滤,但我在实现它时遇到了问题。
I' having an error in implementing this lines of codes:我在实现这行代码时出错:
function search(text: string, pipe: PipeTransform): Country[] {
return COUNTRIES.filter(country => {
const term = text.toLowerCase();
return country.name.toLowerCase().includes(term)
|| pipe.transform(country.area).includes(term)
|| pipe.transform(country.population).includes(term);
});
}
I can't change the COUNTRIES.filter , I'm getting an error when I try to put/replace my function on it.我无法更改COUNTRIES.filter ,当我尝试在其上放置/替换我的函数时出现错误。 I get this error " Property 'filter' does not exist on type 'void' "
我收到此错误“属性 'filter' 在类型 'void' 上不存在”
Here's my code.这是我的代码。
export class MyComponent implements OnInit {
countries: Observable<any[]>;
filter = new FormControl('');
listQuestions = [];
constructor(private extractorService: ExtractorService,
private fstore: AngularFirestore) { }
ngOnInit() {
this.filterFunction();
}
filterFunction(){
this.countries = this.filter.valueChanges.pipe(
startWith(''),
map(text => this.search(text))
);
}
search(text: string): any[] {
return this.sampleFunction().filter(country => {
const term = text.toLowerCase();
return country.caseID.toLowerCase().includes(term)
|| (country.word).toLowerCase().includes(term)
|| (country.product).toLowerCase().includes(term);
});
}
sampleFunction() {
this.extractorService.dbFirestore().subscribe(data => {
this.listQuestions = data.map(x => {
return x.payload.doc.data();
})
})
}
I can get all the data from firebase from my sampleFunction() .我可以从我的sampleFunction()获取来自 firebase 的所有数据。
BTW I load the data on html using this codes:顺便说一句,我使用以下代码在 html 上加载数据:
<tr *ngFor="let item of countries | async">
Can you please help me to use the data that I get on my sampleFunction() to the search function in where the guide use the lines " return COUNTRIES.filter(country => {
"你能帮我将我在sampleFunction()上获得的数据用于搜索功能,其中指南使用“
return COUNTRIES.filter(country => {
”
You're not returning the observable all the up to the async
pipe.您并没有将可观察对象全部返回到
async
管道。 You're performing a manual subscription instead and mapping the results.您正在执行手动订阅并映射结果。
filterFunction() {
this.countries = this.filter.valueChanges.pipe(
startWith(''),
switchMap(text => this.search(text))
);
}
search(text: string): Observable<any[]> {
return this.sampleFunction().pipe(
map(countries => {
return countries.filter(country => {
const term = text.toLowerCase();
return country.caseID.toLowerCase().includes(term)
|| (country.word).toLowerCase().includes(term)
|| (country.product).toLowerCase().includes(term);
});
});
);
}
sampleFunction(): Observable<any[]> {
return this.extractorService.dbFirestore().pipe(
map(data => data.map(x => x.payload.doc.data()))
);
}
I would recommend adding return types to functions wherever possible, Typescript is great at finding small type-based mistakes like this.我建议尽可能在函数中添加返回类型,Typescript 非常擅长发现像这样的基于类型的小错误。
One potential issue now is that this.extractorService.dbFirestore()
is going to be called every time the filter value changes.现在一个潜在的问题是
this.extractorService.dbFirestore()
将在每次过滤器值更改时调用。 If you don't want this to happen you need a different approach.如果您不希望这种情况发生,则需要采用不同的方法。
You probably just want to load the data first and then filter a fixed array.您可能只想先加载数据,然后过滤固定数组。 In which case, you would load the data first and then chain the value changes onto that with a
concatMap
.在这种情况下,您将首先加载数据,然后使用
concatMap
将值更改链接到该数据上。
filteredCountries$: Observable<any[]>;
private countries: any[];
filterFunction() {
// load the countries first
this.filteredCountries$ = this.getCountries().pipe(
// set the countries
tap(countries => this.countries = countries),
// now start observing the filter changes
concatMap(countries => {
return this.filter.valueChanges.pipe(
startWith(''),
map(text => this.search(text))
})
);
}
search(text: string): any[] {
return countries.filter(country => {
const term = text.toLowerCase();
return country.caseID.toLowerCase().includes(term)
|| (country.word).toLowerCase().includes(term)
|| (country.product).toLowerCase().includes(term);
});
}
getCountries(): Observable<any[]> {
return this.extractorService.dbFirestore().pipe(
map(data => data.map(x => x.payload.doc.data()))
);
}
Then your HTML would be watching filteredCountries$
instead of countries
.然后您的 HTML 将观看
filteredCountries$
而不是countries
。
<tr *ngFor="let item of filteredCountries$ | async">
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.