Как отфильтровать наблюдаемые из Google Firestore - PullRequest
0 голосов
/ 19 мая 2019

Я использую observable из firestore, чтобы заполнить список выбора

getInvoices() {
this.invCollection = this.afs.collection('invoices');
this.invoices = this.invCollection.snapshotChanges().pipe(
  shareReplay(1),
  map(actions => {
  return actions.map(action => ({
    key: action.payload.doc.id,
    ...action.payload.doc.data()
  }))
})
)

this.invList = this.invoices.source;

}

И я делюсь данными из this.inv, наблюдаемыми с this.invList observable

Я хотел бы отфильтровать второй наблюдаемый на основе выбора пользователя

<mat-form-field class="ffield">
    <mat-select (selectionChange)="getInv($event)" placeholder="Choose invoice">
      <mat-option *ngFor="let invoice of invoices | async; trackBy: trackByFn" [value]="invoice.key">{{invoice.invNo}}</mat-option>
    </mat-select>
  </mat-form-field>


getInv(e) {
  this.sID = e.value; //id of selected invoice

  //TODO filter this.invList observable   }

Мне нужна помощь с фильтрацией this.invList observable

Я пробовал что-то вроде

this.invList.pipe(map(aaa => {return aaa.map(bbb => ())}), filter(flt => flt.key === this.sID)).subscribe(sss => (console.log(sss.invNo)))

, ноего не работает, ключ свойства не существует

1 Ответ

1 голос
/ 19 мая 2019

rxjs filter оператор фильтра значений в потоке (ваш массив представляет собой одно значение в потоке), в вашем случае вам не нужно фильтровать значения в потоке, вам нужен map массив значений для конкретного значения по идентификатору .

this.invoices$ = this.invCollection.snapshotChanges().pipe(
  map(actions => 
    actions.map(action => 
      ({
        key: action.payload.doc.id,
        ...action.payload.doc.data()
      })
    )
  )
)

если вам нужно создать поток с элементом по определенному идентификатору:

getInvoiseById(id): Observable<InvoiceType> {
 return this.invoices$.pipe(
   map(invoices => 
     invoices.filter(({key}) => key === id)))
   )
}

если вам нужно создать поток с активным счетом, лучше создать поток с активным идентификатором и объединить его с потоком счета

activeId$ = new Subject<TypeOfIdField>();

activeInvoice$ = combineLatest([
  this.invoices$,
  this.activeId$
]).pipe(
  map(([invoices, id]) => 
    invoices.find(({key}) => key === id)
  )
)

setActiveId(id) {
  this.activeId$.next(id);
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...