GraphQL忽略了一些(但不是全部)任意分配的markdown frontmatter数据

时间:2017-08-26 12:54:02

标签: graphql gatsby

第一次尝试盖茨比,这是一种乐趣。但是我遇到了一个奇怪的GraphQL问题:

我正在使用gatsby-source-filesystem和gatsby-transformer-remark插件从markdown文件中提取内容。

所有这些数据的前置数据都不相同(title除外)。有些人有date字符串(博文),同样有tag数组,有些有gallery个对象。

现在的问题是,一些任意分配的前端数据在GraphQL中可用,而另一些则不是。例如,如果我尝试查询日期,我总是会在类型date上获得“GraphQL错误未知字段frontmatter_2”。然而,如果我查询标签,我会为那些包含一个标签的项目获取标签数组,而为那些没有标签的人获取tags: null

这里有什么问题?如何始终将null作为节点中不存在的字段的值?

可能需要注意的是,此行为会根据我的markdown文件的目录结构而改变。如果我移动它们,GraphQL中的一些前端字段可用,以前不是,反之亦然。在通过HMR推送一些代码更改之后,也会发生一些字段变得可用 - 但是在我重新启动Gatsby之后,尽管没有触及其间的代码,它们仍然会消失。

非常感谢你的帮助!

修改

在我的头撞到这一段时间失败后,我采取了确保所有降价前线具有相同类型的相同字段的方法。

我想

  

TODO链接到自动推断类型/字段的文档。

documentation的一部分是关于这个问题的。

当我有更多时间时,我想了解更多关于GraphQL及其在Gatsby中的工作原理。任何指针都赞赏。

1 个答案:

答案 0 :(得分:2)

您可能会遇到this错误,有时人们似乎错过了GraphQL中人口稀少的字段。

但是,要回答您的具体问题,您如何确保始终获得null空字段。你可以使用onCreateNode钩子来做到这一点。每个节点都会调用此挂钩。

类似以下伪代码的东西将实现您的目标:

exports.onCreateNode = ({node, getNode, boundActionCreators}) => {
  const { createNodeField } = boundActionCreators

  if (_.get(node, 'internal.type') === `MarkdownRemark`) {

    // Repeat this for each field
    createNodeField({
      node,
      name: 'date',
      value: _.get(node, 'frontmatter.date', 'default date'),
    })

  }
}

这会将值从frontmatter复制到fields,并确保它们始终存在一些默认值(如果它们尚不存在)。您可以在node.internal.type上添加测试以过滤特定节点类型

注意:这是完全未经测试的,不包括袖口,伪代码,使用风险自负!