Rendering JSON with GraphQL in GatsbyJS

I’ve been stuck hours and I have no idea what’s wrong. I’m new to GraphQL and Gatsby.

I have a JSON that I’m trying to render. Each object should have its own url path. I’m able to query the data with GraphQL, set up CreatePages in my gatsby-node.js file and then query again in my template file, but for some reason I’m only getting null in the template.

I’m pretty sure I’m using gatsby-plugin-transformer-json too. I’m at a loss right now. Any help is much appreciated.

gatsby-node.js

/**
 * Implement Gatsby's Node APIs in this file.
 *
 * See: https://www.gatsbyjs.org/docs/node-apis/
 */

// You can delete this file if you're not using it
const path = require('path');

exports.createPages = ({actions, graphql}) => {
	const { createPage } = actions;
	const postTemplate = path.resolve(`src/templates/post.js`);
	const projectTemplate = path.resolve(`src/templates/project.js`);

	return graphql(`{
		allProjectsJson {
		    edges {
		      node {
		        id
		        name
		        description
		        path
		      }
		    }
		  }
		allMarkdownRemark {
			edges {
				node {
					html
					id
					frontmatter {
						path
						title
						date
					}
				}
			}
		}
	}`)
	.then(res => {
		if(res.errors) {
			return Promise.reject(res.errors);
		}
		// blogs
		res.data.allMarkdownRemark.edges.forEach(({node}) => {
			createPage({
				path: node.frontmatter.path,
				component: postTemplate
			})
		})
		// projects
		res.data.allProjectsJson.edges.forEach(({node}) => {
			createPage({
				path: node.path,
				component: projectTemplate
			})
		})
	})
}

templates/project.js

import React from 'react';
import { graphql } from 'gatsby'
import Layout from "../components/layout"
// import Helmet from 'react-helmet';

export default function Project({data}) {
	const { projectsJson: project } = data;
	console.log(data)
	return (
		<Layout>
			<div>
				<h1>Projects!!!</h1>
				<p>One single</p>
			</div>
		</Layout>
	);
}

export const projectQuery = graphql`
  query ProjectByPath($path: String!) {
  	projectsJson(path: { eq: $path }) {
  		name
  		path
  		description
  	}
  }
`
1 Like

Thought I’d provide a solution that worked for me in case anyone else comes across this post.

Given a json file (all-projects.json) with the following contents:

[
  {
    "projects": [
      {
        "id": 1,
        "name": "My Project 1",
        "description": "My description 1",
        "path": "#"
      },
      {
        "id": 2,
        "name": "My Project 2",
        "description": "My description 2",
        "path": "#"
      }
    ]
  }
]

Formatting the json this way seems a lot cleaner too me and you don’t have to deal with edges > node…

This is the query:

const data = useStaticQuery(
    graphql`
      query ProjectsQuery {
        allProjectsJson {
          projects {
            id
            name
            description
            path
          }
        }
      }
    `
  );

const { projects } = data.allProjectsJson;

Now you can iterate over your projects, e.g.,

projects.map(({id, name, description, path}) => {
  // Logic here
});
2 Likes