Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow optional GraphQL data in Gatsby

I'm trying to build a Type in my gatsby-node.js file that supports an optional value. Which I think is done with [String!]!.

How can I load the new Type that I've created inside gatsby-node.js on home.js?

gatsby-node.js:

const path = require('path');
exports.createSchemaCustomization = ({ actions }) => {
    const { createTypes } = actions;
    const typeDefs = `
        type markdownRemark implements Node {
            frontmatter: Features
        }
        type Features {
            title: [String!]!
            description: [String!]!
        }
    `;
    createTypes(typeDefs);
};

pages/home/home.js:

export const query = graphql`
    query HomeQuery($path: String!) {
        markdownRemark(frontmatter: { path: { eq: $path } }) {
            html
            frontmatter {
                features {
                    title
                    description
                }
            }
        }
    }
`;

home.md:

---
path: "/"
features:
    - title: Barns
      description: Praesent commodo cursus magna vel scelerisque nisl consectetur et. Nullam id dolor id nibh ultricies vehicula ut id elit.
    - title: Private Events
      description: Praesent commodo cursus magna vel scelerisque nisl consectetur et. Nullam id dolor id nibh ultricies vehicula ut id elit.
    - title: Food and Drinks
      description: Praesent commodo cursus magna vel scelerisque nisl consectetur et. Nullam id dolor id nibh ultricies vehicula ut id elit.
    - title: Spa
      description: Praesent commodo cursus magna vel scelerisque nisl consectetur et. Nullam id dolor id nibh ultricies vehicula ut id elit.
---

This needs to work so that if the features array inside home.md's front matter is empty, then GraphQL doesn't throw an error.

Please don't tell me to always include at least one value in the array, because this isn't practical, my solution needs to support no values in my array.

I've spent two hours going through documentation/issues in circles trying to find a working solution, please can someone save me!

like image 606
Luke Brown Avatar asked Feb 18 '20 20:02

Luke Brown


People also ask

Does Gatsby require GraphQL?

Gatsby uses source plugins to pull in data. Note: GraphQL isn't required: you can still use Gatsby without GraphQL. To source data with an existing plugin you have to install all needed packages.

How does GraphQL work in The Great Gatsby?

Using a special syntax, you describe the data you want in your component and then that data is given to you. Gatsby uses GraphQL to enable page and StaticQuery components to declare what data they and their sub-components need. Then, Gatsby makes that data available in the browser when needed by your components.

How does Gatsby fetch data from API?

Fetching data at build time In order to fetch data at build time, you can use a source plugin or source data yourself. To source data yourself you can create an integration with a third-party system by creating nodes for the GraphQL layer in your gatsby-node file from retrieved data that becomes queryable in pages.


1 Answers

From the GraphQL docs:

  • String! means that the field is non-nullable, meaning that the GraphQL service promises to always give you a value when you query this field. In the type language, we'll represent those with an exclamation mark.
  • [Episode!]! represents an array of Episode objects. Since it is also non-nullable, you can always expect an array (with zero or more items) when you query the field. And since Episode! is also non-nullable, you can always expect every item of the array to be an Episode object.

The exclamation point ! in GraphQL means non-nullable, so [String!]! means that there is a non-null array of non-null strings.

If you want a field to be optional, just leave it as it is without exclamation points !. For example [String] means that the array can be null, or any of the string values inside it can be null.

I'm also not sure that you want to be using an array in the first place, since title and description of a feature should surely just be a single string?

As per the Gatsby docs, I think what you're looking for is this:

const typeDefs = `
    type markdownRemark implements Node {
        // Use custom frontmatter type
        frontmatter: Frontmatter
    }
    // Define custom frontmatter type
    type FrontMatter {
      // Nullable array of Feature elements
      features: [Feature]
    }
    // Feature has nullable fields title and description
    type Feature {
        title: String
        description: String
    }
`;

This means that frontmatter has a field called features that can be null (optional) and if it does exist, is an array of Feature objects. It can be empty, but if any Feature objects exist, each Feature has a nullable (optional) title and description field.

like image 99
JMadelaine Avatar answered Oct 17 '22 19:10

JMadelaine