You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 19:09:03