编辑 - 添加新文档时 Firebase 时间戳在 HTML 插值中导致 'Cannot read properties of null' 错误
EDIT - Firebase Timestamp Causing 'Cannot read properties of null' error in HTML interpolation while adding new document
session.startDate 是一个 firebase 时间戳,我在 HTML 中使用 toDate() 函数和日期管道对其进行转换。这非常有效,直到我开始通过服务添加文档。
{{session.startDate.toDate() | date}}
添加新文档后,虽然所有内容都能在屏幕上正确呈现,但我收到大量愤怒的控制台消息:
ERROR TypeError: Cannot read properties of null (reading 'toDate')
因此,我猜测当服务添加文档时,在填充 startDate 之前有足够的时间,因此 .toDate() 函数会失败,直到数据存在。
我确定我要做的事情很简单,我只是不确定我应该在项目中的什么时候等待数据,以及最好的方法。
为此,我使用了 2 个组件:显示组件和服务组件。
显示组件
当显示首次加载时,我获取当前路由 ID,并将 sessionSource 设置为订阅的 sessionService。
ngOnInit(): void {
this.subscribe = this.activatedRoute.paramMap.subscribe(params => {
this.pid = params.get('pid');
})
this.sessionService.getSessionList(this.pid).subscribe((value) => {
this.sessionSource = value
});
}
然后在HTML,我运行 *ngFor 显示不同文件的列表。
<mat-expansion-panel *ngFor=" let session of sessionSource"
<mat-expansion-panel-header>
<mat-panel-title>
{{session.startDate.toDate() | date}}
</mat-panel-title>
<mat-panel-description>
{{session.sessionDescription}}<div *ngIf="session.active"> - Active Session</div>
</mat-panel-description>
</mat-expansion-panel-header>
</mat-expansion-panel>
会话服务
当我使用我的服务添加新会话时,这就是 运行(请注意,有一些正在进行的 'return' 功能可以获取新创建的文档 ID 以用于我还没有的路由还在工作)。
添加新条目成功,并按预期显示在页面上,但出现上述错误。
startNewSession(pid: string){
return this.afs.collection("/Management/"+pid+"/Sessions").add({
active: true,
startDate: firebase.firestore.FieldValue.serverTimestamp(),
sessionDescription: 'Testing Adding'
}).then(docRef => {
return docRef.id
}).catch(error => console.error("Error adding document: ", error))
}
好吧,解决方案非常简单,但我花了一段时间才弄清楚问题出在哪里。最后,我回到了我在 medium 上第一次使用 firebase 时间戳时读过的一篇文章。有很多细节,但结果是,在时间戳最终确定之前,它将默认返回一个空值,这就是导致我的空错误的原因。
解决方案是使用“SnapshotOptions”修改每个文档快照,并估计时间戳是多少。我不需要纳秒精度,所以这非常适合我的使用。
最后,我的更改甚至不在我最初发布的内容中,它在服务内部并且是 returns ngOnIt 中对 sessionSource 的订阅。
下面是整个部分,但我所做的只是添加 { serverTimestamps: 'estimate' } 作为 payload.doc.data() 函数的选项。这组是估计的时间戳,我不再有空错误。
getSessionList(pid: string){
return this.afs.collection(this.CollectionPath+pid+'/Sessions', ref => ref.orderBy('startDate', 'desc')).snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const data = a.payload.doc.data({ serverTimestamps: 'estimate' }) as sessions_list;
const id = a.payload.doc.id;
return { id, ...data };
})
}
))
}
有一个similar question我在寻找解决方案时发现的
session.startDate 是一个 firebase 时间戳,我在 HTML 中使用 toDate() 函数和日期管道对其进行转换。这非常有效,直到我开始通过服务添加文档。
{{session.startDate.toDate() | date}}
添加新文档后,虽然所有内容都能在屏幕上正确呈现,但我收到大量愤怒的控制台消息:
ERROR TypeError: Cannot read properties of null (reading 'toDate')
因此,我猜测当服务添加文档时,在填充 startDate 之前有足够的时间,因此 .toDate() 函数会失败,直到数据存在。
我确定我要做的事情很简单,我只是不确定我应该在项目中的什么时候等待数据,以及最好的方法。
为此,我使用了 2 个组件:显示组件和服务组件。
显示组件 当显示首次加载时,我获取当前路由 ID,并将 sessionSource 设置为订阅的 sessionService。
ngOnInit(): void {
this.subscribe = this.activatedRoute.paramMap.subscribe(params => {
this.pid = params.get('pid');
})
this.sessionService.getSessionList(this.pid).subscribe((value) => {
this.sessionSource = value
});
}
然后在HTML,我运行 *ngFor 显示不同文件的列表。
<mat-expansion-panel *ngFor=" let session of sessionSource"
<mat-expansion-panel-header>
<mat-panel-title>
{{session.startDate.toDate() | date}}
</mat-panel-title>
<mat-panel-description>
{{session.sessionDescription}}<div *ngIf="session.active"> - Active Session</div>
</mat-panel-description>
</mat-expansion-panel-header>
</mat-expansion-panel>
会话服务 当我使用我的服务添加新会话时,这就是 运行(请注意,有一些正在进行的 'return' 功能可以获取新创建的文档 ID 以用于我还没有的路由还在工作)。
添加新条目成功,并按预期显示在页面上,但出现上述错误。
startNewSession(pid: string){
return this.afs.collection("/Management/"+pid+"/Sessions").add({
active: true,
startDate: firebase.firestore.FieldValue.serverTimestamp(),
sessionDescription: 'Testing Adding'
}).then(docRef => {
return docRef.id
}).catch(error => console.error("Error adding document: ", error))
}
好吧,解决方案非常简单,但我花了一段时间才弄清楚问题出在哪里。最后,我回到了我在 medium 上第一次使用 firebase 时间戳时读过的一篇文章。有很多细节,但结果是,在时间戳最终确定之前,它将默认返回一个空值,这就是导致我的空错误的原因。
解决方案是使用“SnapshotOptions”修改每个文档快照,并估计时间戳是多少。我不需要纳秒精度,所以这非常适合我的使用。
最后,我的更改甚至不在我最初发布的内容中,它在服务内部并且是 returns ngOnIt 中对 sessionSource 的订阅。
下面是整个部分,但我所做的只是添加 { serverTimestamps: 'estimate' } 作为 payload.doc.data() 函数的选项。这组是估计的时间戳,我不再有空错误。
getSessionList(pid: string){
return this.afs.collection(this.CollectionPath+pid+'/Sessions', ref => ref.orderBy('startDate', 'desc')).snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const data = a.payload.doc.data({ serverTimestamps: 'estimate' }) as sessions_list;
const id = a.payload.doc.id;
return { id, ...data };
})
}
))
}
有一个similar question我在寻找解决方案时发现的