无法在类型“y”上查询字段“x”
Posted
技术标签:
【中文标题】无法在类型“y”上查询字段“x”【英文标题】:Cannot query field "x" on type "y" 【发布时间】:2021-02-03 21:26:25 【问题描述】:我需要一些关于 Graphql 查询的帮助 :)。 我正在尝试将投资组合网站部署到 Netlify,在部署期间,我收到此错误。 我的代码在本地主机上工作,但不在 Netlify 上。 我需要从 Contentful 中提取数据并用它填充图片库。
预期结果: Netlify 部署我的代码
我得到的结果: 构建错误。
There was an error in your GraphQL query:
2:51:25 AM: Cannot query field "tags" on type "ContentfulArt".
2:51:25 AM: If you don't expect "tags" to exist on the type "ContentfulArt" it is most likely a typo.
However, if you expect "tags" to exist there are a couple of solutions to common problems:
2:51:25 AM: - If you added a new data source and/or changed something inside gatsby-node.js/gatsby-config.js, please try a restart of your development server
2:51:25 AM: - The field might be accessible in another subfield, please try your query in GraphiQL and use the GraphiQL explorer to see which fields you can query and what shape they have
2:51:25 AM: - You want to optionally use your field "tags" and right now it is not used anywhere. Therefore Gatsby can't infer the type and add it to the GraphQL schema. A quick fix is to add at least one entry with that field ("dummy content")
2:51:25 AM: It is recommended to explicitly type your GraphQL schema if you want to use optional fields. This way you don't have to add the mentioned "dummy content". Visit our docs to learn how you can define the schema for "ContentfulArt":
https://www.gatsbyjs.org/docs/schema-customization/#creating-type-definitions
Gatsby-node.js 文件
enter code here
const path = require('path')
module.exports.createPages = async (graphql, actions) =>
const createPage = actions
const portfolioTemplate = path.resolve('./src/templates/gallerylist.js')
const data = await graphql(
`
query
allContentfulArt
edges
node
title
tags
publishedDate(formatString:"MMMM Do, YYYY")
image
file
url
`
)
//error handling
//amount of images per page = 8
const imgPerPage = 8
const numPages = Math.ceil(data.allContentfulArt.edges.length / imgPerPage)
//we calculate math ceiling from the total amount of objects in our query by edges.length then divide it by 8.
//we create page for each index in Numpages, ignoring the callback with "_,", path = path where we will create pages
//component - template that contain the endpoints for our create page code
//context - information to pass down into the created page
Array.from(length:numPages).forEach((_, i) =>
actions.createPage(
path: i === 0 ? `/portfolio/$1` : `/portfolio/$i + 1`,
component:portfolioTemplate,
context:
limit: imgPerPage,
skip: i * imgPerPage,
numPages,
currentPage: i + 1
)
)
我的模板文件
import React from 'react'
import graphql from 'gatsby'
import Zoom from 'react-medium-image-zoom'
import Footer from '../components/footer'
import Header from '../components/header'
import Head from '../components/head'
import 'react-medium-image-zoom/dist/styles.css'
import Pagination from '../components/pagination'
import portfoliostyles from '../pages/portfolio.module.scss'
const GalleryList = ( pageContext, data) =>
const currentPage, numPages = pageContext
const isFirst = currentPage === 1
const isLast = currentPage === numPages
/*if prev page equals to currentpage -1 we return return to the first page, otherwise we go down 1 page*/
const prevPage = currentPage - 1 === 1 ? `/portfolio/$1` : `/portfolio/$currentPage - 1`
/*next page = currentpage + 1*/
const nextPage = `/portfolio/$currentPage + 1`
/* this will return a div container that conain gallery page
we are passing data via different predefined constants and variables
*/
return (
<div className=portfolioStyles.maincontainergallery>
<Head title="Gallery" />
<div className=portfolioStyles.headercomponent>
<Header />
/* Header container that includes menu and a pagination */
<div className=portfolioStyles.portfoliopagepaginationcontainer>
/* This is pagination component with passed down props to manage the pagination */
<Pagination
isFirst=isFirst
isLast=isLast
prevPage=prevPage
nextPage=nextPage/>
</div>
</div>
/* This is a gallery div container that receives data from Graphql query*/
<div className=portfolioStyles.portfoliopagegallerycontainer>
<div className=portfolioStyles.portfoliopagegallery>
data.allContentfulArt.edges.map((edge) =>
return (
//we grabbing data from Contenful API using Graphql query
//Zoom allows us to click-zoom the images passed down from Contenftul API
<figure className=portfolioStyles.portfoliopagegalleryfigure >
<h3 >
<figcaption>
edge.node.title
</figcaption>
</h3>
<p>edge.node.tags</p>
<p>edge.node.publishedDate</p>
<Zoom>
<img src=edge.node.image.file.url alt=edge.node.title/>
</Zoom>
</figure>
)
)
</div>
</div>
/* this is a footer container with a footer component */
<div className=portfolioStyles.portfoliopagefootercontainer>
<Footer />
</div>
</div>
)
/* This is graphql query to grab the code from a Contentful API */
export const pageQuery = graphql`
query($skip: Int!, $limit: Int!)
allContentfulArt(skip: $skip, limit: $limit)
edges
node
title
tags
publishedDate(formatString:"MMMM Do, YYYY")
image
file
url
`
export default GalleryList
【问题讨论】:
【参考方案1】:这是因为您的 Contentful 架构 allContentfulArt
已将 tags
字段定义为字符串,并且默认情况下不能为空。它总是期望一个结果被填充,至少一个contentfulArt
。
理想的解决方案是customize your schema by adding a type definition
您可以暂时绕过该问题的一件简单的事情是为您的 tags
字段添加一个值,或者在获取数据后添加一个空白值并在之前修剪它。
【讨论】:
您好 Ferran,我尝试添加架构,但仍然遇到同样的错误。 :(我找不到任何关于虚拟内容的信息,我不明白为什么它在本地主机上明确工作时不能在网站上工作:( 您是否在 Netlify 中添加了环境变量,前缀为GATSBY_
?
刚刚尝试将 GATSBY_ 前缀添加到 netlify 上的 env 变量中。同样的交易:)
我通过将 allContentfulArt 更改为 AllcontentfulAssets 解决了这个问题【参考方案2】:
首先,确保您的数据中有tags
的实例。
From the documentation:
目前在 Contentful 构建内容模型时需要牢记一些注意事项。
目前,不会在 GraphQL 架构中创建至少没有一个填充实例的字段。 使用引用字段时,请注意此源插件将自动创建反向引用。您无需为这两种内容类型创建引用。
这是您的错误消息试图通过此消息传达的内容:
您希望有选择地使用您的字段“标签”,现在它没有在任何地方使用。因此 Gatsby 无法推断类型并将其添加到 GraphQL 模式中。一种快速解决方法是添加至少一个带有该字段的条目(“虚拟内容”)。如果您想使用可选字段,建议显式键入您的 GraphQL 架构。这样您就不必添加提到的“虚拟内容”。访问我们的文档,了解如何为“ContentfulArt”定义架构
其次,确保tags
可用。
如果您使用预览 API 来拉取开发中的草稿,您可能还没有发布在 Contentful 中设置了 tags
的内容。当您部署到生产环境并从非预览版 API 中提取时,您的草稿内容将不可用。
最后,确认您拥有 configured your environment variables in Netlify 以包含您的 Contentful 访问令牌。
【讨论】:
我尝试添加架构,但仍然遇到同样的错误。 :(我找不到任何关于虚拟内容的信息,我不明白为什么它在本地主机上可以正常工作时却不能在网站上工作:( 我不知道你的意思是什么都找不到。我将文档的相关部分和错误复制到了我的答案中。只需阅读我的答案并遵循它。 我通过将 allContentfulArt 更改为 AllcontentfulAssets 解决了这个问题 @AlexVoznesenski 我 100% 确定情况并非如此(GraphQL 区分大小写,Gatsby 中根查询对象上的字段名称是小驼峰式),但也许你的意思是allContentfulAssets
。
以上是关于无法在类型“y”上查询字段“x”的主要内容,如果未能解决你的问题,请参考以下文章
带有官方 Graphql 教程的“无法在 CreateUser 类型上查询字段 'id'”
gatsby graphql 无法在“Query”类型上查询字段“allTribeEvents”
GraphQL/Relay Schema 无法在“CreateLinkPayload”类型上查询字段“store”