Handling nested arrays when programmatically creating documents in Sanity.io

16 replies
Last updated: Apr 20, 2021
how do you handle nested arrays when programatically creating documents?I tried something like this

const doc = {
    _type: "testDoc",
    title: "Please work dear sir",
    principle1: {
      _type: "revisions",
      guidelineName: "Pleas work dear madam",
      guideLineDescription: "Cheeseburgers"
    }
  };
for a block like this

{
      title: "Principle 1",
      name: "principle1",
      type: "array",
      of: [{ type: 'generatorAccessibilityGuidelines' }]
    },
I also have to handle one or two lower levels of nesting
Apr 19, 2021, 8:11 PM
title: “Please work dear sir”,
🤣 Pleading with your code. Been there.
Apr 19, 2021, 8:39 PM
It's been a long day and the sanity docs for generating pages seem extra skinny today 😞, but like with so many things - once I find the solution it is obvious
Apr 19, 2021, 8:46 PM
Is
generatorAccessibilityGuidelines
an object type with just
guidelineName
and
guidelineDescription
as fields?
Apr 19, 2021, 8:47 PM
Understanding this spaghetti bowl takes some time but yes essential, only it's documents instead of documents because me and preview was not friends earlier this week.
https://gist.github.com/AndreasJacobsen/a44851ba77675bcba9dc0924a2717733 <- the code
I don't mind making them objects again if that helps, they really don't have to be documents
Apr 19, 2021, 8:53 PM
how it looks
Apr 19, 2021, 8:56 PM
Oh, description is portable content…
Apr 19, 2021, 8:56 PM
yes, I have to generate a whole bunch of data; and a whole bunch of portable text
Apr 19, 2021, 8:57 PM
I didn’t include the boolean or array, but I imagine you’ll want something like this to create the guideline name and description:

{
  "_type": "testDoc",
  "title": "Please work dear sir",
  "principle1": [
    {
      "_type": "generatorAccessibilityGuidelines",
      "_key": "ea93048a4e37e9b23g79b761c706b980",
      "guidelineName": "Please work dear madam",
      "guidelineDescription": [
        {
          "_type": "block",
          "_key": "345ferr09a8w",
          "style": "normal",
          "markDefs": [],
          "children": [
            {
              "_type": "span",
              "_key": "8d8765cv944e",
              "text": "Cheeseburgers"
            }
          ]
        }
      ]
    }
  ]
}
I’ve hardcoded keys. You can probably come up with something programmatically—I think the only requirement is that keys be unique within an array.
Apr 19, 2021, 9:08 PM
hmmm I could probably generate the data by just creating block content and copy pasting the output. They are never re-used on pages. Gonna try this first thing tomorrow, thanks
user A
! Sanity should start paying you soon ;)
Apr 19, 2021, 9:16 PM
hmm the block content data is not associated with the actual portable text component. I tried adding the name but still got an error
const doc = {
    "_type": "testDoc",
    "title": "Please work dear sir",
    "principle1": [
      {
        "_type": "generatorAccessibilityGuidelines",
        "_key": "ea93048a4e37e9b23g79b761c706b980",
        "guidelineName": "Please work dear madam",
        "guidelineDescription": [
          {
            "_type": "block",
            "_key": "345ferr09a8w",
            "name": "guideLineDescription",
            "style": "normal",
            "markDefs": [],
            "children": [
              {
                "_type": "span",
                "_key": "8d8765cv944e",
                "text": "Cheeseburgers"
              }
            ]
          }
        ]
      }
    ]
  };

Apr 19, 2021, 9:25 PM
oh I completly forgot, I'm going to use the results from a GROQ-query to build this generator, so formatting the block content may not be that hard after all. but the mock data needs to work first
Apr 19, 2021, 9:28 PM
oh I completly forgot, I'm going to use the results from a GROQ-query to build this generator, so formatting the block content may not be that hard after all. but the mock data needs to work first
Apr 19, 2021, 9:28 PM
This is how I set up my schema:

export default {
  name: 'generatorAccessibilityGuidelines',
  type: 'object',
  fields: [
    {
      name: 'guidelineName',
      type: 'string'
    },
    {
      name: 'guidelineDescription',
      type: 'array',
      of: [{ type: 'block' }]
    }
  ]
}
Apr 19, 2021, 10:16 PM
I solved this, for any one interested here is how
const generatorTemplate = (revision) => {
  const template = {
    _type: "revisionTemplate",
    auditName: "Well hello there",
    principleOneDescription: revision.principleOneDescription,
    principleTwoDescription: revision.principleTwoDescription,
    principleThreeDescription: revision.principleThreeDescription,
    principleFourDescription: revision.principleFourDescription,
    wadDescription: revision.wadDescription,
    principleOne: revision.principleOne,
    principleTwo: revision.principleTwo,
    principleThree: revision.principleThree,
    principleFour: revision.principleFour,
    wadPrinciples: revision.wadPrinciples,
  };
  return template;
};
export default generatorTemplate;

const createDoc = () => {
    client.create(generatorTemplate(revision)).then((res) => {
      console.log(`testDoc was created, document ID is ${res._id}`);
    });
  };
Data comes from a GROQ-query. Sanity just magically adds all the data to all the nested array elements
Apr 20, 2021, 1:43 PM
Well that’s way nicer. Nice job!
Apr 20, 2021, 1:44 PM
Thanks, your examples really helped me understand things 🙂
Apr 20, 2021, 1:44 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?