Angular使用concat先存Firebase图片再存数据库时img为空问题
问题原因
你创建save$ Observable时就同步读取了this.service.form.value,这个时机远早于Firebase上传完成、回填img字段的时间点,所以service.save()方法拿到的是还没更新的旧表单数据,img字段自然为空。concat操作符只会控制Observable的订阅顺序,不会改变你提前传入save()的参数值,所以即使上传逻辑先执行,save$用的还是提前捕获的旧表单数据。
另外你pushedFile$里的map没有返回值,所以最后订阅拿到的是undefined,可以按需调整。
修复方案
方案1:链式调用(推荐)
把上传和保存操作通过concatMap串联,等到上传完成、表单回填后再构造保存请求:
// 调整upload方法直接返回Observable,无需挂载到实例 upload(): Observable<void> { const file = this.selectedFiles.item(0); this.selectedFiles = undefined; let currentFileUpload = new FileUpload(file); return this.service.pushFileToStorage(currentFileUpload).pipe( map(url => { this.service.form.patchValue({ img: url }); console.log("inside upload:", this.service.form.value) }) ); } onSubmit() { this.upload().pipe( // 上传完成后再读取最新的表单值发起保存请求 concatMap(() => this.service.save(this.service.form.value)) ).subscribe({ next: (saveResult) => { console.log("save data: ", saveResult); }, error: (err) => { console.error("操作失败:", err); } }) }
方案2:用defer延迟save$的构造
如果要保留原有concat的写法,可以用defer包裹保存逻辑,让它等到被订阅的时候才读取最新的表单值:
import { defer } from 'rxjs'; onSubmit() { this.upload(); // defer会在Observable被订阅时才执行内部逻辑,此时上传已完成、表单已更新 let save$ = defer(() => this.service.save(this.service.form.value)).pipe( map(data => console.log("save data: ", data)) ); concat(this.pushedFile$, save$).subscribe((data => console.log("subscription: ", data))); }
内容的提问来源于stack exchange,提问作者Samir Mustafa
相关产品推荐
相关产品推荐

