✨Discover storytelling in the AI age with Pixar's Matthew Luhn at Sanity Connect, May 8th—register now

Issue setting value of JSON field with document action in Sanity Studio

11 replies
Last updated: Apr 22, 2020
Have a little conundrum for you. I'm trying to set the value of a field with a document action. The field is of type
json
using the sanity-plugin-json-input. I retrieve some values from the document when the user hits publish, produce some JSON from the data and attempt to set the value of a readOnly field before letting the doc publish. The JSON field flashes with what seems to be the correct data for a sec before I get an error from the studio:

{
  "response": {
    "body": {
      "error": {
        "description": "Name contains invalid characters",
        "type": "validationError"
      }
    },
    "url": "<https://o5w1jb7v.api.sanity.io/v1/data/mutate/production?returnIds=true&visibility=async>",
    "method": "POST",
    "headers": {
      "content-length": "86",
      "content-type": "application/json; charset=utf-8"
    },
    "statusCode": 400,
    "statusMessage": ""
  },
  "statusCode": 400,
  "responseBody": "{\n  \"error\": {\n    \"description\": \"Name contains invalid characters\",\n    \"type\": \"validationError\"\n  }\n}",
  "details": {
    "description": "Name contains invalid characters",
    "type": "validationError"
  }
}
I've tried stringifying the JSON before attempting to set the value, but then I get a type error, as the field doesn't want strings. Even tried
JSON.parse(JSON.stringify(...))
in a bit of a desperate try, but nope.
Any idea?
(Love document actions btw
❤️ )
Apr 22, 2020, 8:44 AM
Here is my Document Action code.
import { useState, useEffect } from 'react';
import { useDocumentOperation } from '@sanity/react-hooks';
import { processData } from '../../lib/datamachine';

export default function SetAndPublishAction(props) {
  const { patch, publish } = useDocumentOperation(props.id, props.type);
  const [isPublishing, setIsPublishing] = useState(false);
  const [newSlug, setNewSlug] = useState('');
  useEffect(() => {
    // if the isPublishing state was set to true and the draft has changed
    // to become `null` the document has been published
    if (isPublishing && !props.draft) {
      setIsPublishing(false);
    }
  }, [props.draft]);

  return {
    disabled: publish.disabled,
    label: isPublishing ? 'Publishing…' : 'Publish',
    onHandle: async () => {
      // This will update the button text
      setIsPublishing(true);

      // Set publishedAt to current date and time
      if (props.type === 'report') {
        const { odCsv, cidCsv, urlsJson } = props.draft;
        const frankenData = await processData(cidCsv, odCsv, urlsJson);
        patch.execute([
          {
            set: { frankenCode: frankenData },
          },
        ]);
      }

      // Perform the publish
      publish.execute();

      // Signal that the action is completed
      props.onComplete();
    },
  };
}
Apr 22, 2020, 8:45 AM
Wondering about the error message here:
Name contains invalid characters
. That seems to suggest the issue is not with the JSON? Have you tried submitting a most basic JSON string in
frankenData
(instead of
await processData(cidCsv, odCsv, urlsJson);
) to see if it gets picked up?
Apr 22, 2020, 8:59 AM
Wondering about the error message here:
Name contains invalid characters
. That seems to suggest the issue is not with the JSON? Have you tried submitting a most basic JSON string in
frankenData
(instead of
await processData(cidCsv, odCsv, urlsJson);
) to see if it gets picked up?
Apr 22, 2020, 8:59 AM
Hmm. When I set the line in question to:
set: { frankenCode: { foo: 'bar' } },
It works. Even though that is formatted as a plain JS object the Studio let's it fly without question.
Apr 22, 2020, 9:12 AM
So, it seems the invalid name complaint actually does pertain to the JSON. I'm gonna try to reformat all my keys to something JS-friendly and see what happens.
Apr 22, 2020, 9:13 AM
Seems like it indeed, but that’s useful information too 🙂 Hope the reformatting makes it sing!
Apr 22, 2020, 9:15 AM
That was it. The data was being treated as an JS object, and so it fucked up when it encountered keys with spaces in them. Which is super weird, but thanks a bunch for setting me on the right course. 🙂
Apr 22, 2020, 9:19 AM
Glad you found the solution! And really cool to see you work with document actions after being one of the first persons to try them out 🙂 Should it be somewhere in the (plugin) documentation that data is being treated as a JS object?
Apr 22, 2020, 9:28 AM
I think perhaps this is on the json-plugin? I guess under normal circumstances it expects string input and recombobulate it into json, but when set programmatically it seems to expect neither string or json but a JS-object. I'll do some checking to verify, and perhaps put in a pull request adding a comment about it.
Apr 22, 2020, 9:49 AM
That makes sense, thanks Martin - also for considering to make a PR.
Apr 22, 2020, 10:00 AM
Actually, I guess maybe something should be done with the plugin, unless I'm being very dim at the moment. Because the plugin will not accept valid JSON if it has keys that are not valid JavaScript or even keys that would work in bracket notation, such as
myObject['my cool key']
.
Apr 22, 2020, 12:46 PM

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?