Как фильтровать данные, поступающие из базы данных Firestore - PullRequest
0 голосов
/ 16 марта 2020

Я хочу реализовать эту фильтрацию в моем коде, но у меня возникла проблема с ее реализацией.

FILTERING

У меня есть ошибка в реализации этой строки кодов:

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);
  });
}

Я не могу изменить COUNTRIES.filter , я получаю сообщение об ошибке при попытке включить / заменить свою функцию Это. Я получаю эту ошибку " Свойство 'filter' не существует для типа 'void' "

Вот мой код.

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();
      })
    })
  }

Я могу получить все данные из firebase из моей sampleFunction () .

Кстати, я загружаю данные на html, используя следующие коды:

<tr *ngFor="let item of countries | async">

Можете ли вы помочь мне использовать данные что я получаю по моей sampleFunction () функции поиска, где руководство использует строки "return COUNTRIES.filter(country => {"

1 Ответ

2 голосов
/ 16 марта 2020

Вы не возвращаете наблюдаемое все до async трубы. Вместо этого вы выполняете ручную подписку и отображаете результаты.

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()))
  );
}

Я бы порекомендовал добавлять типы возвращаемых данных в функции везде, где это возможно, Typescript отлично подходит для поиска небольших ошибок на основе типов, таких как:

Одна потенциальная проблема сейчас заключается в том, что this.extractorService.dbFirestore() будет вызываться каждый раз, когда изменяется значение фильтра. Если вы не хотите, чтобы это произошло, вам нужен другой подход.

Работа со стати c data

Возможно, вы просто хотите сначала загрузить данные, а затем отфильтровать фиксированный массив. В этом случае вы сначала загрузите данные, а затем объедините изменения значений с помощью 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()))
  );
}

Тогда ваш HTML будет наблюдать filteredCountries$ вместо countries.

<tr *ngFor="let item of filteredCountries$ | async">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...