wordpressgraphqlgatsbywp-graphql

Gatsby: How can I pass multiple context IDs to a single query?


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.


Solution

  • 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
                  }
                }
              }
            }
          }
        }
      }
    `;