将带有动态行数据的Angular反应形式添加到Firestore

时间:2019-12-04 11:07:16

标签: angular firebase google-cloud-firestore

我有一个使用角材料制作的角反应形式。 在这种形式下,我希望用户能够在预算标题下方添加预算项目,以便预算行是动态的。您可以添加行并动态删除它们。

表单的输出如下:

    { 
   "name":"December 2019 House Budget",
   "startDate":"2019-12-04T10:52:04.016Z",
   "desc":"My household stuffs",
   "budgetList":[ 
      { 
         "itemName":"Groceries",
         "itemCost":200
      },
      { 
         "itemName":"Rent",
         "itemCost":600
      },
      { 
         "itemName":"Entertaiment",
         "itemCost":150
      },
      { 
         "itemName":"Water bills",
         "itemCost":50
      }
   ]
}

在我的component.ts中,我有onSubmit()

onSubmit(value, formDirective: FormGroupDirective) {
    console.log(JSON.stringify(value));
    this.mainservice.createBudget(value)
    .then(
      res => {
        formDirective.resetForm();
        this.addBudget.reset();
      }
    )
  }

然后在服务中,我具有createBudget()函数,如下所示。

createBudget(value) {
    return this.firestore.collection('budgets').add({
      name: value.name,
      startDate: value.startDate,
      desc: value.desc,
      budgetList: {
        itemName: value.budgetList.itemName,
        itemCost: value.budgetList.itemCost
      }
    })
  }

但是我收到此错误:

ERROR FirebaseError: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field budgetList.itemName)
    at new FirestoreError (http://localhost:4200/vendor.js:163869:28)
    at ParseContext.push../node_modules/@firebase/firestore/dist/index.cjs.js.ParseContext.createError (http://localhost:4200/vendor.js:184098:16)
    at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseScalarValue (http://localhost:4200/vendor.js:184457:27)
    at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseData (http://localhost:4200/vendor.js:184323:29)
    at http://localhost:4200/vendor.js:184339:41
    at forEach (http://localhost:4200/vendor.js:163973:13)
    at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseObject (http://localhost:4200/vendor.js:184338:13)
    at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseData (http://localhost:4200/vendor.js:184292:25)
    at http://localhost:4200/vendor.js:184339:41
    at forEach (http://localhost:4200/vendor.js:163973:13)

问题是我应该如何将此类数据发送到Firestore? 另一件事:如何为每个其他项目分配一个ID?

我是Firebase的新手;)

2 个答案:

答案 0 :(得分:1)

我知道value就是您刚开始粘贴为“表单输出”的对象。因此value的结构与您要添加到集合中的文档的结构完全相同。因此,您应该像这样添加该对象:

createBudget(value) {
    return this.firestore.collection('budgets').add(value)
}

我已经直接在GCP控制台上的节点中对此进行了测试,如下所示:

const {Firestore} = require('@google-cloud/firestore');

var value = { 
   "name":"December 2019 House Budget",
   "startDate":"2019-12-04T10:52:04.016Z",
   "desc":"My household stuffs",
   "budgetList":[ 
      { 
         "itemName":"Groceries",
         "itemCost":200
      },
      { 
         "itemName":"Rent",
         "itemCost":600
      },
      { 
         "itemName":"Entertaiment",
         "itemCost":150
      },
      { 
         "itemName":"Water bills",
         "itemCost":50
      }
   ]
}

// Create a new client
const db = new Firestore();

db.collection('test').add(value)

这是结果:

enter image description here

答案 1 :(得分:0)

我会将其发布为格式的答案,但是我不确定这是否可行,请告诉我:

根据this,您必须首先为要添加的列表项创建一个uid。但是为此,您需要首先创建一个预算(按照您的示例)。

所以我相信你应该:

以自己的方式创建新预算。但是保存该uid(从保存位置返回的uid),然后添加回调以推送新列表项。

像这样:

// initialize budgetList inside the new budget as an empty object {}
createBudget(value) {
    return this.firestore.collection('budgets').add({
      name: value.name,
      startDate: value.startDate,
      desc: value.desc,
      budgetList: {}
    })
  }

const newBudget = createBudget(value); // get id for newBudget
const budgetList = this.firestore.collection('budgets')[newBudget]; // get the list;

const newBudgetListUid = budgetList.push().key;
newBudgetListUid.set(childList);

或:

// I'm assuming folders inside firestore work like this. But maybe they don't. I'm investigating to update if I'm wrong.
createBudget(value) {
    const list = this.firestore.collection('budgets').add({
      name: value.name,
      startDate: value.startDate,
      desc: value.desc,
      budgetList: {}
    });

    const budgetList = list.budgetList.push().key;
    const budgetList.set({
      itemName: value.budgetList.itemName,
      itemCost: value.budgetList.itemCost
    });
  }

我在这里假设很多东西,但也许这个主意足以使您找到解决方案(如果可以的话,请对其进行评论,以便我可以编辑评论)。