Sanity transaction.patch().set() is not a function error when updating posts

1 replies
Last updated: May 29, 2023
hey, in my StudioNavbar.tsx I want to fetch posts from instagram, it previously worked when I only fetch and inport new posts, but now I'm trying to update the media URL of existing ones at the same time. here's my function:const fetchInstagramPosts = async () => {
const existingPosts = await client.fetch(

      *[ _type == "instagramPost" ] {
        _id,
        instagramId
      }
    
);
try {
const url = `
https://graph.instagram.com/me/media?fields=id,media_url,timestamp&access_token=${INSTAGRAM_KEY} `; const res = await fetch(url);
const data = await res.json();
if (!data || !data.data) {
console.error(
"Error: Instagram API returned an unexpected response",
data
);
return;
}

// Create a transaction for creating or updating the documents
const transaction = client.transaction();

for (const post of data.data) {
const existingPost = existingPosts.find(
(p: any) => p.instagramId === post.id
);

if (existingPost) {
// Update the existing post's mediaUrl
transaction.patch(existingPost._id).set({
mediaUrl: post.media_url,
timestamp: post.timestamp,
});
} else {
// Create a new document
const newPost = {
_type: "instagramPost",
instagramId: post.id,
mediaUrl: post.media_url,
timestamp: post.timestamp,
articleLink: "
https://www.nordkurier.de/ ", // set a default value };

transaction.create(newPost);
}
}

// Commit the transaction
await transaction.commit();
} catch (error) {
console.error("Error fetching Instagram posts", error);
}
};

But I receive this error:
Error fetching Instagram posts TypeError: transaction.patch(...).set is not a function

Can someone help me?
AI Update

The issue you're encountering is with the method chaining syntax for the Sanity client's transaction API. The patch() method doesn't support chaining .set() in transactions the way you're trying to use it.

Here's the corrected syntax for your function:

const fetchInstagramPosts = async () => {
  const existingPosts = await client.fetch(
    `*[_type == "instagramPost"] {
      _id,
      instagramId
    }`
  );
  
  try {
    const url = `https://graph.instagram.com/me/media?fields=id,media_url,timestamp&access_token=${INSTAGRAM_KEY}`;
    const res = await fetch(url);
    const data = await res.json();
    
    if (!data || !data.data) {
      console.error("Error: Instagram API returned an unexpected response", data);
      return;
    }
    
    const transaction = client.transaction();
    
    for (const post of data.data) {
      const existingPost = existingPosts.find(
        (p: any) => p.instagramId === post.id
      );
      
      if (existingPost) {
        // Correct syntax: pass the patch spec as the second argument
        transaction.patch(existingPost._id, {
          set: {
            mediaUrl: post.media_url,
            timestamp: post.timestamp,
          }
        });
      } else {
        const newPost = {
          _type: "instagramPost",
          instagramId: post.id,
          mediaUrl: post.media_url,
          timestamp: post.timestamp,
          articleLink: "https://www.nordkurier.de/",
        };
        transaction.create(newPost);
      }
    }
    
    await transaction.commit();
  } catch (error) {
    console.error("Error fetching Instagram posts", error);
  }
};

The key change is in how you call patch(). Instead of:

transaction.patch(existingPost._id).set({ ... })

Use:

transaction.patch(existingPost._id, { set: { ... } })

The patch operation in Sanity transactions takes the document ID as the first argument and a patch specification object as the second argument. The patch spec object should contain the operation type (set, unset, setIfMissing, etc.) as a key with the fields to modify as its value.

This should resolve your "transaction.patch(...).set is not a function" error and allow you to update existing Instagram posts while creating new ones in a single transaction.

Show original thread
1 reply
Hi Max. That doesn’t appear to be the right API for
transaction()
. Could you please try changing this:

transaction.patch(existingPost._id).set({
  mediaUrl: post.media_url,
  timestamp: post.timestamp,
});
to this:


transaction.patch(client.patch(existingPost._id).set({
  mediaUrl: post.media_url,
  timestamp: post.timestamp,
}));
Which, if we remove the abstraction, is effectively this:


client
  .transaction()
  .patch(
    client
      .patch(existingPost._id)
      .set({
        mediaUrl: post.media_url,
        timestamp: post.timestamp,
      })
  )
  .commit() // I'm assuming this happens later in your code and works

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?