Проблемы с загрузкой массива безопасно в моем угловом шаблоне HTML - PullRequest
0 голосов
/ 24 мая 2019

У меня есть массив, который заполняется после .subscribe для моего API. Консоль показывает, что он заполнен, как и ожидалось. Доступ к элементу массива приводит к ошибке, возникшей из-за того, что он не определен

<div *ngIf="!invoices || invoices.length === 0">
       No invoices
</div>
<div *ngIf="invoices || async ">
      {{ invoices[0]?.invoice_id || async}}
</div>

Если я удалю оператор elvis, мой контент будет нормально загружаться, однако консоль будет выдавать ошибки InvoicesComponent.html:10 ERROR TypeError: Cannot read property 'invoice_id' of undefined, пока массив не будет заполнен функцией подписки.

Массив счетов инициализируется в моем сервисе

 invoices: Array<Invoice> = [];

И я заполняю массив

getInvoices(){
   var _invoices = this.invoices;
   if(this.afAuth.user){
      // users/uid/invoices/invoice_id/
      var userRef = this.afs.doc(`users/${this.afAuth.auth.currentUser.uid}`)

 userRef.collection('invoices').get().subscribe(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
        // doc.data() is never undefined for query doc snapshots
        console.log(doc.id, " => ", doc.data());
        _invoices.push({
          'invoice_id': doc.id, 
          'customer_company': doc.data().customer_company, 
          'year_id':doc.data().year_id, 
          'date_created': doc.data().date_created, 
          'date_modified': doc.data().date_modified})
    });
    console.log(_invoices)
});
return _invoices
}

По предложению Тричетриче был создан класс Invoice

import { QueryDocumentSnapshot } from  "@angular/fire/firestore";
import { of } from 'rxjs'

export class Invoice {
    invoice_id: string;
    customer_company: string;
    date_created: string;
    date_modified: string;
    year_id: string;

constructor(invoiceDoc: QueryDocumentSnapshot<any>){
    this.invoice_id = invoiceDoc.id
    this.customer_company = invoiceDoc.data().customer_company
    this.date_created = invoiceDoc.data().date_created
    this.date_modified = invoiceDoc.data().date_modified
    this.year_id = invoiceDoc.data().year_id
}

    toObservable(){
        return of(this)
    }
}

Ответы [ 3 ]

0 голосов
/ 24 мая 2019

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

вы можете передать Observable непосредственно в шаблон, и код будет выглядеть так:

   <div *ngIf="invoices|async as invoicesList; else noInvoices">
     {{ invoicesList[0]?.invoice_id}}
   </div>
   <ng-template #noInvoices>
     <div  >
       No invoices
     </div>
   </ng-template>
0 голосов
/ 27 мая 2019

Сразу после некоторых исследований кажется, что мне лучше подписаться на наблюдаемые и работать с данными, когда они поступают из моего API с помощью асинхронного канала.

Итак, мои последние функции выглядят примерно так:

ngOnInit() {
    this.observableInvoices = this.auth.getObservableInvoices().pipe(map( 
      (data) => data));
    console.log(this.observableInvoices)
    }
<li *ngFor="let invoice of observableInvoices | async; index as i">
  getObservableInvoices(): Observable<any> {
    this.observable_invoices = this.afs
      .collection(`users/${this.afAuth.auth.currentUser.uid}/invoices`)
      .valueChanges() as Observable<any[]>;
    return this.observable_invoices;
  }
0 голосов
/ 24 мая 2019

Оригинал

<div *ngIf="!invoices || invoices.length === 0">
       No invoices
</div>
<div *ngIf="invoices || async ">
      {{ invoices[0]?.invoice_id || async}}
</div>

Отредактировано

<ng-container *ngIf="invoices | async as invoicesSync; else noInvoices">
  <p>{{ invoicesSync[0]?.invoice_id || 'No ID for invoice' }}</p>
</ng-container>
<ng-template #noInvoices>
  <p>No invoices</p>
</ng-template>

1 - Это | async, а не || async: | - это труба, || - это откат кложное утверждение.
2 - в вашем коде должен быть один асинхронный код, который создает переменную шаблона через as XXX.
3 - вам не нужно несколько условий.Используйте один с оператором then.

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