Graphql:如果参数类型为字符串则跳过参数

Posted

技术标签:

【中文标题】Graphql:如果参数类型为字符串则跳过参数【英文标题】:Graphql: skip a parameter if its type is string 【发布时间】:2020-09-09 23:13:21 【问题描述】:

我有一个针对 Markdown 文件的 graphql 查询,它从 Markdown 的前端请求 titleauthorcoverImg

有些 Markdown 文件没有封面图片,当没有图片时,看起来 coverImg 的类型是 String

我正在使用gatsby-image,它使用sharp,如果coverImg 是一个对象而不是字符串,我想下降到coverImg 参数的子级


这是我的查询

query($path: String!) 
    markdownRemark(fields:  slug:  eq: $path  ) 
        frontmatter 
            title
            author
            coverImg 
              childImageSharp 
                fluid(maxWidth: 600) 
                  src
                  srcSet
                  sizes
                  aspectRatio
                
              
           
        
     
 

如果我尝试这个,我会收到错误

There was an error in your GraphQL query:

Field "cover" must not have a selection since type "String" has no subfields.

This can happen if you e.g. accidentally added   to the field "cover". If you didn't expect "cover" to be of type "String" make sure that your input source and/or plugin is correct.

看起来有graphql if statements,但我不知道如何使用这些有条件地分支到孩子。如果我可以添加类似

的内容,那就太好了
 coverImg @skip(if: coverImg is String) 

【问题讨论】:

通常我处理这些的方式只是检查图像是否存在于组件本身中:if (frontmatter.coverImg.childImageSharp) <Img fluid=frontmatter.coverImg.childImageSharp.fluid />。这对你的情况不起作用吗? 架构自定义可能会有所帮助github.com/gatsbyjs/gatsby/issues/18271 【参考方案1】:

AFAIK Gatsby 不会基于每个文件推断您的数据架构,因此一旦推断字段为String,该字段将始终为String 类型。

您可以使用模式自定义钩子告诉 Gatsby 字段 coverImg 是一个文件(正如 @ksav 在评论中所建议的那样):

exports.createSchemaCustomization = ( actions ) => 
  actions.createTypes(`
    type MarkdownRemarkFrontmatter @infer 
      coverImg: File
    

    type MarkdownRemark implements Node @infer 
      frontmatter: MarkdownRemarkFrontmatter
    
  `)

然后你可以检查coverImg是否存在。

if (!coverImg) 
  // no image
 else if (coverImg.childImageSharp) 
  // has image
 else 
  // file is not an image

【讨论】:

对不起,我有点困惑,我到底要把这段代码放在哪里?我把它放在我的gatsby-node.js 文件中,但它没有解决任何问题 是的,它应该放在 gatsby-node.js 中——它告诉 Gatsby 字段 coverImg 应该始终为 null 或图像文件。我刚刚注意到一个类型名称是错误的,所以我已经解决了这个问题。如果它不起作用,则可能是您的设置中的其他内容。一个最小的可重复示例将大大有助于让其他人帮助您。 所以它帮助了原来的错误,但我现在得到了这个warn You can't use childImageSharp together with undefined.undefined — use publicURL instead. The childImageSharp portion of the query in this file will return null: 我的程序以一种我不想这样做的不同方式运行。如果我有时间,我会发布一个最小可重复的例子 我尝试了你的解决方案来处理一个不同的 frontmatter 图像,它总是有一个值,并收到错误 You can't use childImageSharp together with undefined.undefined — use publicURL instead. The childImageSharp portion of the query in this file will return null:TypeError: article.node.frontmatter.featuredImage.childImageSharp is null 好像我保持所有代码相同,只是删除了 customSchemaCustomization我的gatsby-node.js 的功能然后我的网站建立没有问题【参考方案2】:

认为应该可以使用graphql union types 做你想做的事。我从来没有在对象和字符串上使用它们,但应该有办法做到这一点?

【讨论】:

以上是关于Graphql:如果参数类型为字符串则跳过参数的主要内容,如果未能解决你的问题,请参考以下文章

我想使用语言 java 在 graphql 查询参数中使用字符串数组

Flutter / GraphQL - 以自定义类型为参数的突变

Python:如果条件为真,则跳过 For 循环中的迭代

Type-GraphQL 的参数错误 - 没有参数类型?

Apollo GraphQl 分页 - 限制和跳过

GraphQL - Gatsby.js- React 组件。 - 如何查询变量/参数?