簡體   English   中英

Angular Lifecycle Hook - 異步數據未定義 OnInit

[英]Angular Lifecycle Hook - Async data undefined OnInit

我正在嘗試訪問從 firestore 文檔加載的對象中的數組,但無法在 ngOnInit 中操作它,因為在幾秒鍾后它在 DOM 中呈現之前,它是未定義的。

因此,我無法設置填充了我需要訪問的數組中的數據的新材料 MatTableDatasource,並且在嘗試這樣做時,CLI 返回

Observable 類型上不存在屬性“items”

視圖=invoice.component.ts:

import { Component, OnInit, AfterViewInit, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { MatPaginator, MatTableDataSource, MatSort } from '@angular/material';
import { Observable } from 'rxjs/Observable';

import { AngularFireDatabase } from 'angularfire2/database';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';

import { AuthService } from '../../services/auth.service';
import { InvoiceService } from '../invoice.service';

import { Invoice } from '../invoiceModel';

@Component({
  selector: 'app-view-invoice',
  templateUrl: './view-invoice.component.html',
  styleUrls: ['./view-invoice.component.scss']
})

export class ViewInvoiceComponent implements OnInit, AfterViewInit {

  userId: string;
  invoiceId: string;
  invoice: Observable<Invoice>;
  items: object[];

  itemsData = new MatTableDataSource();

  tableColumns = [
    'description'
  ]

  constructor(private authService: AuthService, private invoiceService: InvoiceService, private db: AngularFirestore, private route: ActivatedRoute) {
    this.userId = this.authService.user.uid;

    this.route.params.subscribe(params => {
        this.invoiceId = params.id;
    })

    this.db.collection('/users').doc(this.userId).collection('/invoices').doc(this.invoiceId).ref.get().then(snapshot => {
        this.invoice = snapshot.data() as Observable<Invoice>;
        this.itemsData = this.invoice.items; <-- Here. "Property items does not exist on 'Observable<Invoice' "...
    })

  }

  ngOnInit() {

  }

  ngAfterViewInit() {

  }

}

回答新版本

由於您有幾個需要在鏈中調用的 observables:

  • 您的 API 調用取決於可觀察參數的結果,
  • 設置數據字段取決於API調用的結果
  • 之間似乎有一些觀察結果

所以你應該使用flatMap來幫助你鏈接可觀察的調用。

this.route.params
    .map(params => params.id)
    .do(id => { 
        // you can remove this block completely if you don't have other use of this.invoiceId
        this.invoiceId = id; 
    }) 
    .flatMap(invoiceId => Observable.fromPromise(
        this.db.collection('/users').doc(this.userId).collection('/invoices').doc(invoiceId).ref.get())))
    .flatMap(snapshot$ => snapshot$) // not completely sure if needed, try with or without this line
    .flatMap(snapshot => snapshot.data() as Observable<Invoice>)
    .subscribe(
        invoice => { 
            this.itemsData.data = invoice.items; 
            console.log('Loaded items : ');
            console.log(invoice.items);
        }, 
        err => {
            console.log('There was an error :');
            console.log(err);
        }
     ); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM