Gatsby:如何将多个上下文 ID 传递给单个查询?

问题描述

我正在尝试使用它们的 wordpress ID 从单个查询中的两个单独对象获取数据,但我得到了 GraphQLError: The ID input is invalid. Make sure you set the proper idType for your input.wordpress 中使用 GraphQL IDE 它按预期获取所有数据,但我得到我的代码中的那个错误。例如,如果我将 idType 设置为字符串,则会得到 Variable "$editorId" of type "String!" used in position expecting type "ID!".

gatsby-node.js > createPages 函数

// 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,});
  });

页面模板查询

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

盖茨比信息:

  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 

我没有运气发现我做错了什么。

解决方法

你的 gatsby-node.js 看起来很完美。您的问题是由您发送到模板 (videoDetailTemplate) 的数据上下文类型引起的。您告诉 GraphQL ideditorId 都是 ID 类型,而我猜它们应该是字符串。

我想改变这一行:

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

这应该可以解决问题:

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

正如您从 GraphQL types definition docs 中看到的:

ID 标量类型表示唯一标识符,通常用于 重新获取对象或作为缓存的键。 ID类型是序列化的 以与字符串相同的方式;但是,将其定义为 ID 表示 它不是人类可读的。

注意:找出字符串和 ID 类型之间的区别(“将其定义为 ID 表示它不是人类可读的”)

您应该能够在插件设置中为每个字段配置类型:

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",},],}

此外,您应该能够在通过上下文发送时使用 parseIntNumberString 等方法强制类型。

然后按照文档建议使用 where 过滤器:

editorDetailPage(where: { id: $editorId})

videoDetailPage (where: { id: $id})

您能否提供有关您的实现(插件、配置、版本等)的更多详细信息?这似乎是一个错误:

资源:

,

搞定了。需要在 editorDetailPages 列表上使用 where 查询。非常感谢 Ferran Buireu 为我指明了正确的方向。

gatsby-node.js > createPages 函数:

// 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),});
  });

页面模板查询:

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