skip to Main Content

I’m trying to get data from two separate objects in a single query using their WordPress IDs, but I’m getting GraphQLError: The ID input is invalid. Make sure you set the proper idType for your input. Using the GraphQL IDE in WordPress it fetches all the data as expected, but I get that error in my code. If I set the idType to a string, for example, I get Variable "$editorId" of type "String!" used in position expecting type "ID!".

gatsby-node.js > createPages function:

// Video Detail pages
  const {
    data: {
      cartel: { videoDetailPages },
    },
  } = await graphql(`
    query {
      cartel {
        videoDetailPages(first: 300) {
          nodes {
            id
            slug
            videoDetail {
              editor
              editorId
            }
          }
        }
      }
    }
  `);

  const videoDetailTemplate = path.resolve(`./src/templates/videoDetail.js`);

  videoDetailPages.nodes.forEach(page => {
    const editorSlug = page.videoDetail.editor.replace(' ', '-').toLowerCase();
    const { editorId } = page.videoDetail;

    createPage({
      // will be the url for the page
      path: `${editorSlug}/${page.slug}`,
      // specify the component template of your choice
      component: slash(videoDetailTemplate),
      // In the ^template's GraphQL query, 'id' will be available
      // as a GraphQL variable to query for this page's data.
      context: {
        id: page.id,
        editorId,
      },
    });
  });

page template query:

export const query = graphql`
  query($id: ID!, $editorId: ID!) {
    cartel {
      videoDetailPage(id: $id) {
        videoDetail {
          client
          director
          duration
          editor
          productionCompany
          videoStill {
            altText
            sourceUrl
          }
          videoUrl
          title
        }
      }
    }
    cartel {
      editorDetailPage(id: $editorId) {
        editorDetail {
          editorVideos {
            pagePath
            image {
              altText
              sourceUrl
              title
            }
          }
        }
      }
    }
  }
`;

gatsby-info:

  System:
    OS: macOS 10.15.7
    CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 10.23.0 - ~/.nvm/versions/node/v10.23.0/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.8 - ~/.nvm/versions/node/v10.23.0/bin/npm
  Languages:
    Python: 2.7.16 - /usr/bin/python
  Browsers:
    Chrome: 91.0.4472.77
    Firefox: 87.0
    Safari: 14.1
  npmPackages:
    gatsby: ^2.24.36 => 2.32.13 
    gatsby-image: ^2.4.14 => 2.11.0 
    gatsby-plugin-accessibilityjs: ^1.0.3 => 1.0.3 
    gatsby-plugin-google-tagmanager: ^2.3.11 => 2.11.0 
    gatsby-plugin-manifest: ^2.4.22 => 2.12.1 
    gatsby-plugin-offline: ^2.2.7 => 2.2.10 
    gatsby-plugin-react-helmet: ^3.3.10 => 3.10.0 
    gatsby-plugin-remove-trailing-slashes: ^2.3.11 => 2.10.0 
    gatsby-plugin-sass: ^2.3.12 => 2.8.0 
    gatsby-plugin-sharp: ^2.6.25 => 2.14.4 
    gatsby-plugin-sitemap: ^2.4.11 => 2.12.0 
    gatsby-plugin-web-font-loader: ^1.0.4 => 1.0.4 
    gatsby-source-filesystem: ^2.3.24 => 2.11.1 
    gatsby-source-graphql: ^3.4.0 => 3.4.0 
    gatsby-transformer-sharp: ^2.5.12 => 2.12.1 

I’m not having any luck finding what I’m doing wrong.

2

Answers


  1. Chosen as BEST ANSWER

    Got it sorted out. Needed to use a where query on the list of editorDetailPages. Thanks very much to Ferran Buireu for guiding me in the right direction.

    gatsby-node.js > createPages function:

    // Video Detail pages
      const {
        data: {
          cartel: { videoDetailPages },
        },
      } = await graphql(`
        query {
          cartel {
            videoDetailPages(first: 300) {
              nodes {
                id
                slug
                videoDetail {
                  editor
                  editorId
                }
              }
            }
          }
        }
      `);
    
      const videoDetailTemplate = path.resolve(`./src/templates/videoDetail.js`);
    
      videoDetailPages.nodes.forEach(page => {
        const editorSlug = page.videoDetail.editor.replace(' ', '-').toLowerCase();
        const { editorId } = page.videoDetail;
    
        createPage({
          // will be the url for the page
          path: `${editorSlug}/${page.slug}`,
          // specify the component template of your choice
          component: slash(videoDetailTemplate),
          // In the ^template's GraphQL query, 'id' will be available
          // as a GraphQL variable to query for this page's data.
          context: {
            id: page.id,
            editorId: parseInt(editorId, 10),
          },
        });
      });
    

    page template query:

    export const query = graphql`
      query($id: ID!, $editorId: Int!) {
        cartel {
          videoDetailPage(id: $id) {
            videoDetail {
              client
              director
              duration
              editor
              productionCompany
              videoStill {
                altText
                sourceUrl
              }
              videoUrl
              title
            }
          }
        }
        cartel {
          editorDetailPages(where: { id: $editorId }) {
            nodes {
              editorDetail {
                editorVideos {
                  pagePath
                  image {
                    altText
                    sourceUrl
                    title
                  }
                }
              }
            }
          }
        }
      }
    `;
    

  2. Your gatsby-node.js looks perfect. Your issue is caused by the types of the data context you are sending to the template (videoDetailTemplate). You are telling to GraphQL that both id and editorId are ID types while I guess they should be strings.

    I guess changing this line:

      query($id: ID!, $editorId: ID!) {
    

    To this should do the trick:

      query($id: String!, $editorId: String!) {
    

    As you can see from GraphQL types definition docs:

    The ID scalar type represents a unique identifier, often used to
    refetch an object or as the key for a cache. The ID type is serialized
    in the same way as a String; however, defining it as an ID signifies
    that it is not intended to be human‐readable.

    Note: spot the difference between String an ID types ("defining it as an ID signifies that it is not intended to be human‐readable")

    You should be able to configure the types for each field in the plugin’s setup:

    module.exports = {
      plugins: [
        {
          resolve: "gatsby-source-graphql",
          options: {
            // Remote schema query type. This is an arbitrary name.
            typeName: "WPGraphQL",
            // Field name under which it will be available. Used in your Gatsby query. This is also an arbitrary name.
            fieldName: "wpcontent",
            // GraphQL endpoint, relative to your WordPress home URL.
            url: "https://example.com/blog/graphql",
          },
        },
      ],
    }
    

    Additionally, you should be able to force the types using parseInt, Number, String, etc, methods at the time you send it through context.

    Then use the where filter as the documentation suggests:

    editorDetailPage(where: { id: $editorId})
    
    videoDetailPage (where: { id: $id})
    

    Can you provide more details about your implementation (plugins, configurations, versions, etc)? It seems to be a bug:

    Resources:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search