Brett DeWoody
Brett DeWoody

Reputation: 62861

Gatsby buildObjectType for array of items

I have a field that contains an array of Strings - in this case it's an array of filenames, but it could be IDs or any identifier. I'd like to use buildObjectType to resolve these Strings to another Node. In other words, resolve an array of Strings to an array of external Nodes.

I have used buildObjectType to resolve a Node from a field containing a single identifier, but haven't been able to get it working when the field is an array of IDs. In the case of a single identifier the resolver is something like:

context.nodeModel
  .getAllNodes({ type: "ChildYaml" })
  .find(child => child.slug === source.child)

Now I need to iterate over an array and resolve each item.

Here's an example of my field in a ParentYaml file

files:
  - filename1
  - filename2
  - filename3
  - filename4

In gatsby-config:

exports.createSchemaCustomization = ({ actions, schema }) => {
  const { createTypes } = actions

  const typeDefs = [
    schema.buildObjectType({
      name: "ParentYaml",
      fields: {
        files: {
          type: "ChildYaml",
          resolve: (source, args, context, info) => {
            // Iterate over context and resolve each item to a filename
          },
        },
      },
    })
  ]

  createTypes(typeDefs)
}

I have tried the following resolve, unsuccessfully. This gets a File Node, but not the ChildYaml.

resolve: (source, args, context, info) => {
  return source.files.map((fileRef) => {
    return context.nodeModel
      .getAllNodes({ type: "File" })
      .find(file => file.name === fileRef)
  })
},

I have also tried a method to resolve the ChildYaml (instead of File) using the slug. This produces a similar result - the resolve returns an array of the desired Nodes, but those Nodes are not available in my page context.

How can I resolve Nodes of an array?

Upvotes: 1

Views: 672

Answers (1)

Brett DeWoody
Brett DeWoody

Reputation: 62861

One of the reasons I love Stack Overflow, and the question-asking process - it encourages you to think of the problem in a different way, take a step back and boil the issue down to the basics.

In writing the question and re-reading it later I took a different approach and tried Gatsby's @link directive.

This format replaced the verbose schema.buildObjectType syntax with the following:

type ParentYaml implements Node {
   files: [ChildYaml] @link(by: "slug")
},

which did exactly what I wanted - the files field now resolves each file into it's own ChildYaml Node.

Upvotes: 2

Related Questions