Использование карты в возвращенном запросе graphql делает известные члены неопределенными

Я использую Гэтсби для создания блога и не могу использовать onCreatePage API для передачи данных из моего запроса graphql в шаблоны страниц.

Мой запрос берет данные из Кентико Облако, и это выглядит так.

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

Это допустимый запрос, и он возвращает данные, которые выглядят следующим образом.

Использование карты в возвращенном запросе graphql делает известные члены неопределенными

Проблема возникает в моем файле 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: Cannot read property 'url_slug' of undefined

  • 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 — это то место, где он спотыкается.

Результат console.table(node.contentItems) непосредственно перед методом createPage таков.

Использование карты в возвращенном запросе graphql делает известные члены неопределенными

Похоже, что у 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: Cannot read property 'value' of undefined.

Я действительно не понимаю, как я могу вести журнал таблицы и видеть элемент url_slug, но затем, когда я пытаюсь получить к нему доступ, он говорит, что он не определен. Все это время я знаю, что мой запрос правильный, потому что я могу запустить его в graphiQL и получить точные данные, которые я ожидаю.

Любая помощь будет оценена по достоинству. Спасибо.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Что такое Apollo Client и зачем он нужен?
Что такое Apollo Client и зачем он нужен?
Apollo Client - это полнофункциональный клиент GraphQL для JavaScript-приложений, который упрощает получение, управление и обновление данных в...
0
0
1 140
2

Ответы 2

Есть ли причина, по которой вы заключаете node в фигурные скобки в аргументе карты?

Возможно, вы уже пробовали это, но моей первой интуицией было бы сделать это вместо этого:

result.data.allKenticoCloudTypeBlogPost.edges.map(node => {  

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

});

К сожалению, фигурные скобки необходимы, так как данные возвращаются следующим образом: edges — это массив объектов с одним свойством node. Мне лично не нравится, как это выглядит, но это удобнее, чем разворачивать ребро в теле функции.

Derek Nguyen 01.03.2019 06:37

В результате вашего запроса node.contentItems представляет собой массив, хотя вы пытаетесь получить к нему доступ, как если бы это был объект:

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

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

Я думаю, что ваше замешательство, вероятно, связано с тем, как console.table отображает данные. Это сбивает с толку, если вы еще не знаете форму своих данных. На вашем снимке экрана показано, что этот объект имеет 4 свойства с индексом 0 -> 3 (поэтому, вероятно, массив), каждое из которых имеет одно свойство с именем elements (перечислено в заголовке таблицы), которое является объектом с единственным свойством url_slug.


Я не знаком с KenticoCloud, но, возможно, ваши сообщения вложены в contentItems, и в этом случае вам следует перебрать его:

result.data.allKenticoCloudTypeBlogPost.edges.map(({node}) => {        
  node.contentItems.forEach(({ elements }) => {
    createPage({
      path: elements.url_slug.value,
      context: { slug: elements.url_slug.value },
      component: ...
    })

  })
});

Спасибо за ваш ответ Дерек. Это был не ответ, но вы правы, говоря, что node.contentItems - это массив, и я обращался к нему как к объекту. Скоро выложу обновление с решением. Оказывается, я вызывал не ту вещь в graphQL. Как только я это исправил, мой код работал без изменений. Я опубликую обновление в ближайшее время.

onTheInternet 01.03.2019 19:48

Другие вопросы по теме