How to return updated values from a Sanity patch mutation

5 replies
Last updated: Apr 29, 2022
Hello everyone , Could anyone help me out by showing me a way to return updated values from a patch event. I tried in below way but it does not return values in then ( ) function .What I found that patch returns id maximum and we can query the document using that id to fetch values , these are previous values not updated one. Could anyone just point me what goes wrong here....I just want to fetch updated comments after patch event took place. I confirmed update values in sanity studio. Or Give me a general idea , how to return updated values from a patch event. `axios.post (...patch mutation runs here).then((response,data)=>{ console.log(response.data.results[0].id); client.fetch(
*[_type == "blog" && _id == $id][0]
, {`
id: response.data.results[0].id,

})                                                                                                                                                                                                                                                                             .then((x)=>{

console.log(x.comments)

return  res.status(201).send({

message: 'CommentUpdated',

comments: x.comments

})

})

.catch(function (error) {

console.log(error.message);

});                                                                                                                                                                                                                                                                       }).catch(function (error) {

console.log(error.message);

});
AI Update

Based on the Sanity documentation, the issue you're experiencing is common when performing patch mutations. By default, patch mutations only return the document ID, not the updated document content. To get the updated values immediately after your patch, you need to use the returnDocuments parameter.

Solution: Use returnDocuments=true

When making your mutation request, add returnDocuments=true as a query parameter. This tells Sanity to return the full content of changed documents in the response.

With your current axios approach:

axios.post(
  `https://${projectId}.api.sanity.io/${apiVersion}/data/mutate/${dataset}?returnDocuments=true`,
  {
    mutations: [
      {
        patch: {
          id: 'your-blog-id',
          set: { comments: updatedComments }
        }
      }
    ]
  }
)
.then((response) => {
  // The updated document is now directly in the response
  const updatedDoc = response.data.results[0].document;
  console.log(updatedDoc.comments);
  return res.status(201).send({
    message: 'CommentUpdated',
    comments: updatedDoc.comments
  });
})
.catch(function (error) {
  console.log(error.message);
});

Using the Sanity JS Client (recommended):

If you're using the official Sanity JavaScript client, you can use .commit() with options:

client
  .patch(documentId)
  .set({ /* your changes */ })
  .commit({ returnDocuments: true })
  .then((updatedDoc) => {
    console.log(updatedDoc.comments);
    return res.status(201).send({
      message: 'CommentUpdated',
      comments: updatedDoc.comments
    });
  });

Why your current approach doesn't work

When you query the document immediately after patching (without returnDocuments), you're experiencing a race condition. Even though the mutation has been committed, the query might execute before Sanity's real-time index is fully updated, returning the old values instead of the new ones.

Additional helpful options

According to the Mutation API documentation:

  • returnDocuments=true - Returns the entire content of changed documents
  • returnIds=true - Returns only the IDs (default behavior)
  • visibility=sync - Ensures changes are visible to queries before returning (default)
  • visibility=async - Returns immediately after commit (faster, but subsequent queries might not see changes immediately)

By using returnDocuments=true, you get the freshly updated document directly from the mutation response, completely avoiding timing issues with subsequent queries.

Show original thread
5 replies
Thank you so much Racheal.It's now very much clear.
Hello Racheal , could you please tell me where this queue comes from in above code.I mean queue is not defined.
Sure, it's an external package for limiting the rate at which you write to Sanity.
import cq from 'concurrent-queue';

let queue = cq()
  .limit({ concurrency: 25 })
  .process(function (task) {
    return new Promise(function (resolve, reject) {
      setTimeout(resolve.bind(undefined, task), 1000);
    });
  });
Hello Racheal, Thanks for your reply. I am getting error message " oh no update failed : the mutation(s) failed, Insufficient permission "update" required." Do we require to pass token in http header? I have executed the method using mutation after passing token in headers , it throws above error if below function triggered.
handler.use(auth).post(async(req,res)=>{

//method for new comments

//from concurrent-queue package for limiting the rate

let queue = cq()

.limit({ concurrency: 25 })

.process(function (task) {

return new Promise(function (resolve, reject) {

setTimeout(resolve.bind(undefined, task), 1000);

});

});

`const query = `*[_type == 'blog']`;`

const docs = await client.fetch(query);



// Loop through all of the docs returned from our query


for (const doc of docs) {

queue(doc).then(async () => {

// Add a message to help us know the post is happening
`console.log(
Mutating ${doc._id}
);`
// Tell the client to patch the current document

client

.patch(doc._id)

// Set the field

.setIfMissing({ comments: [] })

.insert('after', 'comments[-1]', [

{

name: req.user.name,

rating: Number(req.body.rating),

comment: req.body.comment,

user: {

_type: 'reference',

_ref: req.user._id,

}}

])

.set({

commentsTotalNumber: blog && blog.comments && blog.comments.length,

rating: blog && blog.comments && blog.comments.reduce((a, c) => c.rating + a, 0) / blog.comments.length,

})


// Commit the changes


.commit()

.then((updatedDoc) =>{
`console.log(
Comment is updated! New document:
, updatedDoc)`
res.status(201).send({

message: 'Comment is Posted',

comments: updatedDoc

})


}


)

.catch((err) =>

console.error('Oh no, the update failed: ', err.message)

);



});

}


});
Are you running this script from your root folder using
sanity exec
? If so, you can use the flag --withUserToken to pass in your token.

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?