Gastby-在gastby-node.js中添加带有参数的GraphQL查询

时间:2020-07-17 13:58:53

标签: graphql gatsby contentful

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)
    })
}

因此,我想查询在slug中经过contentfulCaseStudy(slug: { eq: $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] ]
  }

是否可以要求将case作为参数进行特定案例研究?如果是这样,怎么做?

1 个答案:

答案 0 :(得分:1)

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

但是,您尝试使用$slug的方法是通过context API传递变量。

您要实现的流程是:

  • 根据allContentfulCaseStudy的内容数据获取并创建页面
  • 使用slugallContentfulCaseStudy的{​​{1}}中的contentfulCaseStudy来过滤每个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变量,因为您是通过page query中的context传递变量的。所以:

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游乐场,看看嵌套的titleoverview是否在contentfulCaseStudy下,或者您是否需要修改查询结构。

Creating Pages from Data Programmatically阅读也可以为您提供帮助。