Firebase: поместить коллекцию в массив

#angular #typescript #firebase #google-cloud-firestore #ng-bootstrap

#angular #typescript #firebase #google-облако-firestore #ng-bootstrap

Вопрос:

Кто-то уже использовал ng-table в angular и мог понять, как использовать его с firebase collecction?

Я пытаюсь использовать ng-table (последний пример) для сортировки и фильтрации моей коллекции в Angular 10, поэтому я попытался просто изменить константу в коде на свой объект, и у меня это не сработало. Я думаю, мне нужно преобразовать мой объект в массив, поэтому я попробовал эту библиотеку, чтобы сделать это, а также не работает. Также пытался найти это в stackoverflow, и все, что я обнаружил, — это другие с той же проблемой.

Это именно та функция, в которой мне нужно это сделать. COUNTRIES — это массив, который поступает из *countries.ts . Приведенная ниже функция находится в country.service.ts.

   private _search(): Observable<SearchResult> {
    const {sortColumn, sortDirection, pageSize, page, searchTerm} = this._state;

    // 1. sort
    let countries = sort(COUNTRIES, sortColumn, sortDirection);

    // 2. filter
    countries = countries.filter(country => matches(country, searchTerm, this.pipe));
    const total = countries.length;

    // 3. paginate
    countries = countries.slice((page - 1) * pageSize, (page - 1) * pageSize   pageSize);
    return of({countries, total});
  }
}
  

Это то, что я пробовал с библиотекой, которая обнаружила:

 this.items = this.firestore.collection('users').valueChanges();

alert( O2A(this.items) );
  

Но у меня это не работает.

Спасибо!

Комментарии:

1. когда вы вызываете _search() из своего сервиса? и чего вы пытаетесь достичь с помощью метода O2A? ValuesChanges уже возвращает наблюдаемый объект, содержащий массив.

2. Я получил эту ошибку: в типе ‘Observable<User[]>’ отсутствуют следующие свойства из типа ‘User[]’: length, pop, push, concat и еще 25.

3. Вы получаете это, потому что это возвращаемая наблюдаемая величина. Это асинхронный объект, который при подписке отправляет данные в вашу коллекцию каждый раз, когда они обновляются (создание, обновление, удаление в вашей коллекции firebase). Сначала вам нужно подписаться на него, чтобы запросить массив, выполнив следующие действия: this.items.subscribe(res => alert(O2A(res))) . Не забудьте отказаться от подписки, как только она вам станет не нужна, в противном случае вы создадите утечку данных в своем приложении, что негативно скажется на производительности вашего приложения.

4. Все еще ошибка. Не могли бы вы получить полный пример того, как вы решаете эту проблему и изменяете образцы данных для коллекции firebase в ng-table?

5. Можете ли вы отредактировать свой вопрос в соответствии с тем , чего вы пытались добиться после моего комментария? Я понятия не имею о вашей конечной цели и вашей реализации. Ваши два фрагмента кода кажутся мне не связанными. Как они взаимодействуют друг с другом?

Ответ №1:

Я возьму пример, который вы предоставляете для ответа.
Минимальное требование для этого — немного адаптировать country.service. У нас есть изменения в constructor() и private _search() методе. Нам нужно будет заменить COUNTRIES переменную, содержащую массив данных, на ваш массив пользователей (обратите внимание, что вам нужно будет адаптировать весь код в соответствии с вашими атрибутами пользователей):

country.service.ts

 ...
users: User[];

constructor(private pipe: DecimalPipe) {
    this._search$.pipe(
      tap(() => this._loading$.next(true)),
      debounceTime(200),
      switchMap(() => this._search()),
      delay(200),
      tap(() => this._loading$.next(false))
    ).subscribe(result => {
      this._countries$.next(result.users);
      this._total$.next(result.total);
    });
    // this will get your users and start the _search$ above
    this.firestore.collection('users').valueChanges().pipe(take(1)).subscribe(users => {
        this.users = users;
        this._search$.next();
    });
  }
  
  private _search(): Observable<SearchResult> {
    const {sortColumn, sortDirection, pageSize, page, searchTerm} = this._state;

    // 1. sort
    // provide your users (instead of COUNTRIES exemple variable) as a param 
    let users = sort(this.users, sortColumn, sortDirection);

    // 2. filter
    users = users.filter(user => matches(user, searchTerm, this.pipe));
    const total = users.length;

    // 3. paginate
    users = users.slice((page - 1) * pageSize, (page - 1) * pageSize   pageSize);
    return of({users, total});
  }
...
  

Не забудьте соответствующим образом переименовать свои переменные ( users вместо countries ) и ваш тип ( User вместо Country ) в параметрах методов.

Я не буду выполнять всю работу, поскольку она слишком широкая, но, по крайней мере, вы понимаете, как запустить службу с вашими данными firestore.

Измените также интерфейс SearchResult, в противном случае вы получите ошибку компиляции:

 interface SearchResult {
  users: User[];
  total: number;
}
  

Комментарии:

1. Большое вам спасибо! Похоже, это решение для меня. Но у меня возникла проблема с функцией «take», возникли следующие ошибки: не удается найти имя «take». 89 this.firestore.collection(‘users’).valueChanges().pipe(take(1)).subscribe(users => { ~~~~ src/app/pages/users/item.service.ts:90:9 — ошибка TS2740: введите ‘{}’отсутствуют следующие свойства типа ‘User[]’: длина, pop, push, concat и еще 26.

2. Take — это оператор rxjs. Это займет первое излучение и завершит наблюдаемое (вам просто нужен один запрос, чтобы получить ваши данные). Но вам нужно импортировать ее, чтобы использовать ее. Для этого поместите import { take } from 'rxjs/operators'; с другим импортом.

3. Да, спасибо! Я думаю, что я почти на месте. Я только сейчас получаю ошибку, которую получал раньше. Я импортирую свой интерфейс из import {User} из ‘./item’; но все равно получил эту ошибку: тип ‘unknown[]’ не может быть присвоен типу ‘User[]’. В типе ‘{}’ отсутствуют следующие свойства из типа ‘User’: id, bio, birthday, CreatedDate и еще 15. 90 this.users = пользователи;

4. Я изменил this.firestore.collection(‘users’) на this.firestore.collection<User>(‘users’), и это исправило эту ошибку, поэтому я поместил ее на консоль. войдите и получите ошибку, как вы сказали, но все равно не загружайте информацию в таблицу

5. Этот способ возвращает результаты, но создает один массив на каждые 100 регистров. Я редактирую ответ, чтобы показать, что я получаю на консоли