在返回的graphql查询上使用map会使已知成员未定义

时间:2019-02-28 18:43:39

标签: graphql gatsby

我正在使用Gatsbyjs建立博客,而不能使用onCreatePage API将来自graphql查询的数据传递到页面模板中。

我的查询从Kentico Cloud获取数据,看起来像这样。

{
    allKenticoCloudTypeBlogPost{
        edges{
            node{
                contentItems{
                    elements{
                        url_slug{
                            value
                        }
                    }
                }
            }
        }
    }
}

这是一个有效的查询,它返回看起来像这样的数据。

Graphql returned query

问题出在我的gatsby-node.js文件中,我想在其中使用此查询使用我的预定义模板来构建页面。

特别是在看起来像这样的createPage方法中。

result.data.allKenticoCloudTypeBlogPost.edges.map(({node}) => {        
    createPage({
        path: `${node.contentItems.elements.url_slug.value}`,
        component: path.resolve(`./src/templates/blog-post.js`),
        context: {
            slug: node.contentItems.elements.url_slug.value,
        }
    })

});

显示的错误如下。

  

TypeError:无法读取未定义的属性'url_slug'

     
      
  • gatsby-node.js:31 result.data.allKenticoCloudTypeBlogPost.edges.map   C:/ Users / xxxx / Desktop / Marketing Repos / xxxx / gatsby-node.js:31:57
  •   

我决定研究在console.table上进行node.contentItems的过程,因为似乎elements部分是被绊倒的地方。

在createPage方法之前的console.table(node.contentItems)的结果是这个。

table

看来node.contentItems有一个叫做url_slug的成员,而不是我期望的elements成员。

我认为我可以通过这样更新createPage方法调用来解决问题。

result.data.allKenticoCloudTypeBlogPost.edges.map(({node}) => {
    console.table(node.contentItems);

    createPage({
        path: `${node.contentItems.url_slug.value}`,
        component: path.resolve(`./src/templates/blog-post.js`),
        context: {
            slug: node.contentItems.url_slug.value,
        }
    })

});

但随后我收到一条错误消息

  

TypeError:无法读取未定义的属性“值”。

我真的不理解如何执行表日志并查看url_slug成员,但是当我尝试访问它时,它说它是未定义的。一直以来,我都知道我的查询是正确的,因为我可以在graphiQL中运行它并获取我期望的确切数据。

任何帮助将不胜感激。谢谢。

2 个答案:

答案 0 :(得分:1)

在查询结果中,node.contentItems是一个数组,即使您试图像访问一个对象一样访问它:

path: `${node.contentItems.elements.url_slug.value}`,
                           ^^^^^^^^

console.log(contentItems) // [ { elements: {...} }, { elements: {...} }, ... ]

我认为您的困惑可能源于console.table显示数据的方式。如果您还不知道数据的形状,那将会令人困惑。您的屏幕截图显示,该对象具有4个索引为0-> 3的属性(很可能是一个数组),每个属性都有一个名为elements的属性(列在表头上),这是具有唯一属性{{1 }}。


我对KenticoCloud不熟悉,但是也许您的帖子嵌套在url_slug中,在这种情况下,您应该对其进行循环:

contentItems

答案 1 :(得分:0)

您是否有必要在map参数中用大括号包裹节点?

您可能已经尝试过了,但是我的直觉是改为这样做:

 <div id="app">
<div class="row">
  <div class="col-12">

    <h5>V-For</h5>

    <div v-for="i in 4" class="keypad-row">
      <div class="d-inline-block keypad-col p-2" v-for="j in 3" @click="$emit('input', (((i - 1) * 3) +  j))">
        {{((i - 1) * 3) + j}}
      </div>
    </div>
  </div>
</div>

<div class="row">
  <div class="col-12">

    <h5>Manual</h5>

    <div v-for="i in 3" class="keypad-row">
      <div class="d-inline-block keypad-col p-2" v-for="j in 3" @click="$emit('input', (((i - 1) * 3) +  j))">
        {{((i - 1) * 3) + j}}
      </div>
    </div>
    <div class="keypad-row">
      <div class="d-inline-block keypad-col p-2" @click="onClick(10)">
        10
      </div>
      <div class="d-inline-block keypad-col p-2" @click="onClick(11)">
        11
      </div>
      <div class="d-inline-block keypad-col p-2" @click="onClick(12)">
        12
      </div>
    </div>
  </div>
</div>