【问题标题】:Gastby - Add a GraphQL query with parameters in gastby-node.jsGatsby - 在 gatsby-node.js 中添加带有参数的 GraphQL 查询
【发布时间】:2020-11-07 08:29:39
【问题描述】:

gatsby-node.js我有两个从Contentful 获取数据的查询。我想添加一个新查询,它根据特定内容的slug(Contentful 的内容模型中设置的字段)加载特定内容的数据。

这就是我所拥有的:

  return graphql(
    `
      {
        allContentfulBlogPost {
          edges {
            node {
              id
              slug
            }
          }
        }
        allContentfulCaseStudy(filter: { slug: { ne: "dummy-content" } }) {
          edges {
            node {
              id
              slug
            }
          }
        }
        contentfulCaseStudy(slug: { eq: $slug }) { // <=== Here is the problem
          title
          overview
        }
      }
    `
  )
    .then(result => {
      if (result.errors) {
        console.log("Error retrieving contentful data", result.errors)
      }
    })
    .catch(error => {
      console.log("Error retrieving contentful data", error)
    })
}

所以,我想查询在contentfulCaseStudy(slug: { eq: $slug }) 中传递slug 的特定案例研究,但它不起作用。当我启动npm run develop时它会抛出这个错误:

 ERROR #85901  GRAPHQL

There was an error in your GraphQL query:

Variable "$slug" is not defined.

File: gatsby-node.js:13:10

Error retrieving contentful data [
  GraphQLError: Variable "$slug" is not defined.
      at Object.leave (C:\Edited\edited\edited\edited\node_modules\graphql\validation\rules\NoUndefinedVariables.js:38:33)
      at Object.leave (C:\Edited\edited\edited\edited\node_modules\graphql\language\visitor.js:345:29)
      at Object.leave (C:\Edited\edited\edited\edited\node_modules\graphql\language\visitor.js:395:21)
      at visit (C:\Edited\edited\edited\edited\node_modules\graphql\language\visitor.js:242:26)
      at validate (C:\Edited\edited\edited\edited\node_modules\graphql\validation\validate.js:73:24)
      at GraphQLRunner.validate (C:\Edited\edited\edited\edited\node_modules\gatsby\dist\query\graphql-runner.js:79:44)
      at GraphQLRunner.query (C:\Edited\edited\edited\edited\node_modules\gatsby\dist\query\graphql-runner.js:144:25)
      at C:\Edited\edited\edited\edited\node_modules\gatsby\dist\bootstrap\create-graphql-runner.js:40:19
      at Object.exports.createPages (C:\Edited\edited\edited\edited\gatsby-node.js:13:10)
      at runAPI (C:\Edited\edited\edited\edited\node_modules\gatsby\dist\utils\api-runner-node.js:259:37)
      at Promise.catch.decorateEvent.pluginName (C:\Edited\edited\edited\edited\node_modules\gatsby\dist\utils\api-runner-node.js:378:15)
      at Promise._execute (C:\Edited\edited\edited\edited\node_modules\bluebird\js\release\debuggability.js:384:9)
      at Promise._resolveFromExecutor (C:\Edited\edited\edited\edited\node_modules\bluebird\js\release\promise.js:518:18)
      at new Promise (C:\Edited\edited\edited\edited\node_modules\bluebird\js\release\promise.js:103:10)
      at C:\Edited\edited\edited\edited\node_modules\gatsby\dist\utils\api-runner-node.js:377:12
      at tryCatcher (C:\Edited\edited\edited\edited\node_modules\bluebird\js\release\util.js:16:23) {
    locations: [ [Object], [Object] ]
  }

是否可以请求将 slug 作为参数传递的特定案例研究?如果是这样,它是如何完成的?

【问题讨论】:

    标签: graphql gatsby contentful


    【解决方案1】:

    简短的回答是你不能直接。您可以使用硬编码参数进行过滤,而不是使用动态预查询值。

    但是,您尝试对 $slug 执行的操作是通过 context API 传递变量。

    您想要实现的流程是:

    • allContentfulCaseStudy 的内容数据中获取和创建页面
    • 使用contentfulCaseStudy 中的allContentfulCaseStudyslug 来过滤每个contentfulCaseStudy 的查询。

    因此,您需要将您的contentfulCaseStudy 移动到您的template.js,修改您的gatsby-node.js,如下所示:

    exports.createPages = async ({ graphql, actions, reporter }) => {
      const { createPage } = actions
    
      const result = await graphql(
        `
          {
            allContentfulCaseStudy(filter: { slug: { ne: "dummy-content" } }) {
              edges {
                node {
                  id
                  slug
                }
              }
            }
          }
        `
      )
    
      if (result.errors) {
        reporter.panicOnBuild(`Error while running GraphQL query.`)
        return
      }
    
      const caseStudyTemplate= path.resolve(`src/templates/case-study.js`)
    
      result.data.allContentfulCaseStudy.edges.forEach(({ node }) => {
        createPage({
          path,
          component: caseStudyTemplate,
          context: {
            slug: node.slug,
          },
        })
      })
    }
    

    现在,在您的case-study.js 中,您可以使用slug 变量,因为您通过context 在您的page query 中传递它。所以:

    import React from "react"
    import { graphql } from "gatsby"
    import Layout from "../components/layout"
    
    export default function CaseStudy({ data }) {
      const caseStudy= data.contentfulCaseStudy
      return (
        <Layout>
          <div>
            <h1>{caseStudy.title}</h1>
          </div>
        </Layout>
      )
    }
    
    export const query = graphql`
      query($slug: String!) {
            contentfulCaseStudy(slug: { eq: $slug }) {
              title
              overview
            }
      }
    `
    

    检查您的localhost:8000/___graphql Playground,看看嵌套的titleoverview 是否在contentfulCaseStudy 下,或者您是否需要修改查询结构。

    进一步阅读:

    【讨论】:

      猜你喜欢
      • 2021-10-13
      • 2022-07-07
      • 2020-03-23
      • 2020-11-20
      • 1970-01-01
      • 2019-04-02
      • 2019-11-22
      • 2019-06-12
      • 2021-05-28
      相关资源
      最近更新 更多