Reputation: 21
Moving a query from index.js
to midsection.js
(a component) gives Cannot read property of undefined.
I made a website with GatsbyJS which gets it's content from Contentful. I accomplished this by following the Build a blazing fast website with GatsbyJS and Contentful tutorial: https://www.youtube.com/watch?v=wlIdop5Yv_Y
In the tutorial you learn the basics of making a query which shows your content from Contentful on the homepage.
Because I like to use Bulma and I'm pretty new to GatsbyJS (new to React as well) I decided to download the Gatsby-Bulma-Quickstart (https://www.gatsbyjs.org/starters/amandeepmittal/gatsby-bulma-quickstart) and compare it to my own website and use what I need.
I decided to use the component structure used in the Quickstart and wanted to move the query for getting my content from the index.js
to the midsection.js
.
I got everything working until I moved the query.
My index.js
looked like this:
import React from 'react'
import { Link } from 'gatsby'
// import Layout from '../components/layout';
const BlogPost = ({node}) => {
return (
<li>
<Link to={node.slug}><h3>{node.title}</h3></Link>
<img src={node.heroImage.resize.src} />
<div>{node.description.childMarkdownRemark.excerpt}</div>
</li>
)
}
const IndexPage = ({data}) => (
<ul className='blog-post'>
{data.allContentfulBlogPost.edges.map((edge) => <BlogPost node={edge.node} />)}
</ul>
)
// const IndexPage = () => <Layout />;
export default IndexPage
export const pageQuery = graphql`
query pageQuery {
allContentfulBlogPost (filter: {
node_locale: {eq: "en-US"}
},
sort:{ fields: [publishDate], order: DESC }
) {
edges {
node {
title
slug
description {
childMarkdownRemark {
excerpt
}
}
heroImage {
resize(width: 300, height: 300) {
src
}
}
}
}
}
}
`
Note: This works, this shows my content. (But as you can see the components etc from the Quickstart are not included (yet))
This is what my index.js
looks like right now:
import React from 'react'
import Layout from '../components/layout';
const IndexPage = () => <Layout />;
export default IndexPage
And this is what my midsection.js
looks like right now:
import React from 'react'
import { Link } from 'gatsby'
import './style.scss'
const BlogPost = ({node}) => {
return (
<li>
<Link to={node.slug}><h3>{node.title}</h3></Link>
<img src={node.heroImage.resize.src} />
<div>{node.description.childMarkdownRemark.excerpt}</div>
</li>
)
}
const Midsection = ({data}) => (
<ul className="blog-post">
{data.allContentfulBlogPost.edges.map((edge) => <BlogPost node={edge.node} />)}
</ul>
)
export default Midsection
export const pageQuery = graphql`
query pageQuery {
allContentfulBlogPost (filter: {
node_locale: {eq: "en-US"}
},
sort:{ fields: [publishDate], order: DESC }
) {
edges {
node {
title
slug
description {
childMarkdownRemark {
excerpt
}
}
heroImage {
resize(width: 300, height: 300) {
src
}
}
}
}
}
}
`
Using this way of moving the query to a component gives this error in the browser:
TypeError: Cannot read property 'allContentfulBlogPost' of undefined
I'd expected to use the midsection.js
component for columns to show available "blog posts" from Contentful. Instead this only works straight from index.js
.
Is there some way the query is not working because I moved it from the root folder to the components folder? And if so, what do I need to do to get the result I want?
Upvotes: 1
Views: 1299
Reputation: 21
With an colleague helping me, we found an solution by following these steps:
Change layout.js
to:
import './style.scss'
const Layout = ({ children }) => children
export default Layout
Change index.js
to:
import React from 'react'
import Layout from '../components/layout';
import Helmet from '../components/helmet';
import Header from '../components/header';
import Midsection from '../components/midsection';
import Footer from '../components/footer';
const IndexPage = ({data}) => (
<Layout>
<Helmet />
<Header />
<Midsection posts={data.allContentfulBlogPost.edges}/>
<Footer />
</Layout>
)
export default IndexPage
export const pageQuery = graphql`
query pageQuery {
allContentfulBlogPost (filter: {
node_locale: {eq: "en-US"}
},
sort:{ fields: [publishDate], order: DESC }
) {
edges {
node {
title
slug
description {
childMarkdownRemark {
excerpt
}
}
heroImage {
resize(width: 300, height: 300) {
src
}
}
}
}
}
}
`
Change midsection.js
to:
import React from 'react'
import Link from 'gatsby-link'
import './style.scss'
const BlogPost = ({node}) => {
return (
<li>
<Link to={node.slug}><h3>{node.title}</h3></Link>
<img src={node.heroImage.resize.src} />
<div>{node.description.childMarkdownRemark.excerpt}</div>
</li>
)
}
const Midsection = ({ posts }) => (
<ul className="blog-post">
{posts.map(post => (
<BlogPost key={post.node.slug} node={post.node} />
))}
</ul>
)
export default Midsection
So what was the problem and what solved it?
The query used in this situation is a pageQuery which means that it only works from pages found in the pages folder. If you want to use the data in a component you have to pass it through :)
Upvotes: 1