🔮 Sanity Create is here. Writing is reinvented. Try now, no developer setup

Updating object properties in an array on a document with the Sanity client

9 replies
Last updated: Mar 17, 2021
Is it possible to update the property of an object in an array on a document with the Sanity client? Previously I have done simple mutations, like so:
const promises = data.overview.cartContents.map(async (item, index) => {
  return await client.patch(item._id)
  .dec({stock: item.quantity})
  .commit()
});
but I need to do something like this:

const promises = data.overview.cartContents.map(async (item, index) => {
  return await client.patch(item._id)
  .dec({`variants[_key == \"${item.variant}\"].quantity`: item.quantity})
  .commit()
});
(which fails with a
400
error…
Mar 16, 2021, 10:06 PM
What does the 400 error message say?
Mar 16, 2021, 11:11 PM
It’s variations of
'The mutation(s) failed: Cannot increment "variants[].quantity" because it is not present'

I’m losing track of things I’ve tried, but it’s more my uncertainty for lack of an example in the Sanity docs for the Javascript client. I saw this with the HTTP API and wondered if something similar could be done, but think I’m fudging the syntax:


{ "set": "body[_type==\"cta\"].text": "Do the thing!" }

I need to decrement a value in an object in an array, e.g. in my array of
productVariants
find the
productVariant
with
_key == item._key
and then decrement the
stock
property 🙂
I wondered if it could be done something like:

`.dec({`variants[_key == ${item.variant}].quantity`: item.quantity})`

or


.dec({[variants[_key == \"${item.variant}\"].quantity]: item.quantity})

Thanks
user Z
🙂
Mar 16, 2021, 11:18 PM
Just trying some other ideas:

.dec({'variants.0.stock': item.quantity})

which yields:


The mutation(s) failed: Syntax error. (Illegal token "0."

or…


.dec({'variants[].stock': item.quantity})

which yields:


'The mutation(s) failed: Cannot increment "variants[].stock" because it is not present',

So I’m not even managing to adjust all array items, which would be disastrous in reality but a good start!

Is this just not possible with the Javascript client?
Mar 16, 2021, 11:44 PM
OK so this works!

.dec({'variants[0].stock': item.quantity})

Just need to test dynamically…
Mar 16, 2021, 11:47 PM
OK so if I try… `.dec({`variants[${item.variantIndex}].stock`: item.quantity})` I get an
unexpected template string
error
Mar 16, 2021, 11:51 PM
It sounds like the item within the array either didnt exist, or maybe it didn't have a
quantity
already?

.setIfMissing({
  [`variants[_key == \"${item.variant}\"].quantity`]: 0
})
.dec({
  [`variants[_key == \"${item.variant}\"].quantity`]: item.quantity
})
.commit()
Might work if the item exists but doesnt have a quantity
Mar 16, 2021, 11:53 PM
!!!!!! Thank you so much
user Z
I was literally just ham-fistedly working my way towards that one.
`[
variants[${item.variantIndex}].stock
]: item.quantity` is perfect.
This also works too:

`[
variants[_key == \"${item.variant}\"].stock
]: item.quantity`
Your edited example above also works great! –– but only with the square brackets around the template string for me

Combination of me being really dumb (it was
stock
not
quantity
but also not quite having the right syntax anyway – I’m not sure if I’m just generally lacking in essential JS knowledge here (probably :-)) but it seems like a confusing mish-mash of styles to me
Mar 17, 2021, 12:05 AM
Ah, yeah. The square brackets are always a bit confusing
Mar 17, 2021, 12:06 AM
Glad you got it working 🙂
Mar 17, 2021, 12:06 AM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?