I have this colorMap
from firestore which is a map
.
What I'm trying to do is add more data in the colorMap
. Let's say I have these:
Green: 50
Black 50
Red 20
And I wanted to add Pink: 80
. But what my code currently does is, if I'll add Pink: 80
, the Pink
becomes an array instead of a field. Also, there might be instances where I would need to add more colors and quantity in one submission (eg Pink: 80
, Yellow: 20
, Brown: 60
)
This is what happens when I save it in Firestore.
Expected output Once I'll add Black: 80
, it should be the same data types with the other colors as well.
Submitting in firestore:
//converting colorList to colorMap (map)
const colorMap = colorList.reduce(function (map, obj) {
map[obj.color] = obj.colorStocks;
return map;
}, {});
const colorSave = Object.keys(colorMap);
const qty = Object.values(colorMap);
const handleSubmit = (index) => async (e) => {
e.preventDefault();
const ref = doc(db, "products", state);
await updateDoc(ref, {
...product[index],
[`colorMap.${colorSave}`]: qty,
});
console.log("done");
};
This is the console for the colorMap
:
Form
{colorList.map((singleColor, index) => (
<div key={index}>
<>
<>
<TextField
label="Color"
name="color"
type="text"
id="color"
required
value={singleColor.color}
onChange={(e) => handleColorChange(e, index)}
/>
<TextField
label="Stocks"
name="colorStocks"
type="number"
id="colorStocks"
required
value={singleColor.colorStocks}
onChange={(e) => handleColorChange(e, index)}
/>
</>
</>
</div>
<br />
//button to remove the row of the textfield
</div>
))}
//button to add the row of the textfield
The Object.keys(colorMap)
and Object.values(colorMap)
will return arrays . So what you are providing in the updateDoc()
method are not single values rather they are arrays. That is the reason why the value is stored as an array instead of a map.
Now let me explain this a bit further by taking an example -
I have taken a hard coded map for convenience.
If the map has only one object ie const data={'Pink':90}
, then by running the following code as you did,
async function updateData() {
const data={'Pink':90};
const colorSave=Object.keys(data);
const qty=Object.values(data);
const document=doc(db,'collectionId','documentId');
await updateDoc(document,{[`colorMap.${colorSave}`]:qty});
}
will add the data in the Firestore like the following -
If you have more than one object in the map ie const data={'Pink':90,'Red':70}
, then by running the above code as you did, will add the data in the Firestore like the following as colorSave
is an array and also qty
is an array. The field name will be the elements in colorSave
separated by commas.
So the correct way to update the document here is to use a for loop and inside that update the document. The sample code will look something like following -
async function updateData() {
const data={'Pink':90,'Red':70};
const colorSaveArray=Object.keys(data);
const qtyArray=Object.values(data);
const document=doc(db,'collectionId','documentId');
for (let index = 0; index < colorSaveArray.length; index++) {
const colorSave = colorSaveArray[index];
const qty = qtyArray[index];
await updateDoc(document,{[`colorMap.${colorSave}`]:qty});
}
}
The above code will update the document like the following as you want it to be -
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.