Errors
As part of trying to become better with Gatsby and React, I have started answering questions on the official Gatsby Discord server. Sometimes it is pretty easy solving your own problems, but jumping into someone else’s project with a completely different file structure can be a challenge. It’s great practice for me trying to see if I can track down problems other people have.
The Problem
On discord someone was having trouble with a GraphQL query for a template returning `TypeError: Cannot read property ‘markdownRemark’ of undefined` when the template was called.
Well that was not enough information to solve anything, so I requested more information or a repo:
The user was awesome and gave me a link to their GitHub repo which I cloned and dove into. The poor person sounded rather frustrated which was totally understandable after I saw what they were working with.
It was rather complex theme for a beginner to work with, so not surprised they were having difficulties. The original theme had a bunch of templates and one was used for articles generated from .md files. This user wanted that, and another template for projects generated from md files. The `gatsby-node.js` file linked out to a page creation and node creation page that would systematically create a new page in the directory for each entry. The user wanted the projects stored under a `/projets/projectnumber7` type file structure.
First thing I did was a console log in the `src/templates/projects-template.js` file of the props being passed into it.
// @flow strict
import React from 'react';
import { graphql } from 'gatsby';
import Layout from '../components/Layout';
import Project from '../components/Project';
import { useSiteMetadata } from '../hooks';
import type { MarkdownRemark } from '../types';
type Props = {
data: {
markdownRemark: MarkdownRemark
}
};
const ProjectTemplate = ({ data }: Props) => {
console.log(data)
const { title: siteTitle, subtitle: siteSubtitle } = useSiteMetadata();
const { frontmatter } = data.markdownRemark;
......
Already a lot going on. This template was being called from the linked `gatsby-node.js` file each time a markdown file with the frontmatter template type “project” was found.
const { edges } = result.data.allMarkdownRemark;
_.each(edges, (edge) => {
console.log('############',edge.node.frontmatter.template)
if (_.get(edge, 'node.frontmatter.template') === 'page') {
console.log("%%%%%%555555", edge.node.fields.slug)
createPage({
path: edge.node.fields.slug,
component: path.resolve('./src/templates/page-template.js'),
context: { slug: edge.node.fields.slug }
});
} else if (_.get(edge, 'node.frontmatter.template') === 'project') {
console.log("%%%%%%%%%%%%%%%", edge.node.fields.slug)
createPage({
path: edge.node.fields.slug,
component: path.resolve('./src/templates/project-template.js'),
context: { slug: edge.node.fields.slug }
});
I tossed in some console.logs to make sure everything was working as expected. It seemed to be great! I checked a page for the projects being created at [http://localhost:8000/](http://localhost:3000/)projects/myproject7\
and the page was there. It was only when you visited `http://localhost:8000/projects` that the error popped up. So how was the `/projects` page being created? I checked and found the call to create it in the same file linked from `gatsby-node.js`
// projects
createPage({
path: '/projects',
component: path.resolve('./src/templates/projects-template.js')
});
Found it! The `./projects` page was trying to be created using the same template as the actual project pages which were sourced from md files. The `/projects-template.js` file took in the the md file slug as a prop and returned data from a query using it. Since the above code was not passing in any data to be used as the slug in the query, it was failing. Simple solution, create a new template file and call it instead. I could have also created it inside the `/pages` folder and used. There were a few other things that needed to be tweaked to get everything working perfectly as well.
Solved?
And now all that is left is waiting on a reply to see if I was able to help or not.