Я использую Гэтсби для создания блога и не могу использовать onCreatePage API для передачи данных из моего запроса graphql в шаблоны страниц.
Мой запрос берет данные из Кентико Облако, и это выглядит так.
{
allKenticoCloudTypeBlogPost{
edges{
node{
contentItems{
elements{
url_slug{
value
}
}
}
}
}
}
}
Это допустимый запрос, и он возвращает данные, которые выглядят следующим образом.
Проблема возникает в моем файле 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 таков.
Похоже, что у 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 и получить точные данные, которые я ожидаю.
Любая помощь будет оценена по достоинству. Спасибо.


Есть ли причина, по которой вы заключаете 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,
}
})
});
В результате вашего запроса 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. Как только я это исправил, мой код работал без изменений. Я опубликую обновление в ближайшее время.
К сожалению, фигурные скобки необходимы, так как данные возвращаются следующим образом:
edges— это массив объектов с одним свойствомnode. Мне лично не нравится, как это выглядит, но это удобнее, чем разворачивать ребро в теле функции.