Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mismatching revision ID with custom publish action #128

Open
timonforrer opened this issue Mar 11, 2022 · 1 comment
Open

Mismatching revision ID with custom publish action #128

timonforrer opened this issue Mar 11, 2022 · 1 comment

Comments

@timonforrer
Copy link

I'm using a custom publish action to add a custom slug to documents when publishing using a patch:

...
slug = `${pathLangPrefixes[draft?.__lang ?? 'de']}/${slug}`
  
patch.execute([
  {
    set: {
      'pageBase.fullSlug': slug
    }
  }
]);

After that I trigger the publish and call updateIntlFieldsForDocument(), as described here:

publish.execute();
await updateIntlFieldsForDocument(id, type);

However, this triggers the following error in the studio:

An error occurred during publish
Details
the mutation(s) failed: Document "3978c05e-c447-4fc5-94fe-3e6867d23a90" has unexpected revision ID ("9by72vG2l204L0eD67v5lE"), expected "xnBg0xhUDzo561jnWkyoBy"

I assume that the patch creates a new version of the document, which causes the mismatch in the IDs.

The full code for context
import { useState, useEffect } from 'react';
import { useDocumentOperation } from '@sanity/react-hooks';
import sanityClient from 'part:@sanity/base/client';
import slugify from '@sindresorhus/slugify';
import { updateIntlFieldsForDocument } from 'sanity-plugin-intl-input/lib/utils';

const pathLangPrefixes = {
  de: '',
  en: '/en'
}

export default function SetSlugAndPublishAction({ id, type, draft, onComplete }) {
  const { patch, publish } = useDocumentOperation(id, type);
  const [ isPublishing, setIsPublishing ] = useState(false);

  useEffect(() => {
    // if the isPublishing state was set to true and the draft has changed
    // to become `null` the document has been published
    if(isPublishing && !draft) {
      setIsPublishing(false);
    }
  }, [draft]);

  return {
    disabled: publish.disabled,
    label: isPublishing ? 'Publishing…' : 'Publish',
    onHandle: async () => {
      setIsPublishing(true);

      if (draft._type == ('modularPage' || 'blogPost')) {
        const client = sanityClient.withConfig({apiVersion: `2022-01-10`});
  
        const base = draft.pageBase;
  
        let slug = slugify(base.slugBase?.current ?? '');
  
        const query = `*[_id == $ref][0]{"parentSlug": pageBase.slugBase.current}`;
  
        if(base.inheritedParent || base.parent) {
  
          const params = { ref: base.inheritedParent?._ref ?? base.parent?._ref };
          const { parentSlug } = await client.fetch(query, params);
          slug = `${parentSlug}/${slug}`;
  
        }
  
        slug = `${pathLangPrefixes[draft?.__lang ?? 'de']}/${slug}`
  
        patch.execute([
          {
            set: {
              'pageBase.fullSlug': slug
            }
          }
        ]);
      }

      publish.execute();
      await updateIntlFieldsForDocument(id, type);
      if (onComplete) onComplete();
    }
  }
}

Is there a way to fix this problem?

@LiamMartens
Copy link
Owner

The problem is that the executable studio actions (like patch.execute) are not awaitable and async. This means the changes happen in the background but the updateIntlFieldsForDocument function will get called right away before the patch has even fully executed. The only way around this would be to manually patch the document using the studio accessible Sanity client and await.

eg:

import client from "part:@sanity/base/client";

await client.patch(id, { set: {..} })
await updateIntlFieldsForDocument()

This way the revision is properly updated before running the intl update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants