角度生命周期挂钩 - 异步数据未定义 OnInit



我正在尝试访问从firestore文档加载的对象中的数组,但无法在ngOnInit中操作它,因为直到几秒钟后在DOM中呈现它,它是未定义的。

因此,我无法设置一个新的材料 MatTable数据源,其中填充了我需要访问的数组中的数据,并且在尝试这样做时,CLI 返回

属性"项"在可观察类型上不存在

view=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() {
}
}

回答新版本

由于您有几个需要在链中调用的可观察量:

  • 您的 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);
}
); 

最新更新