Search code examples
jsongraphqlgatsby

How can I get data from a json via GraphQL and create dynamic pages in gatsby?


its giving me error Cannot read properties of undefined (reading 'edges') when I deleted edges

 from const {compdata} = data.allJson.edges.node;

its showing same error for node. What is right way to map this and I have to create dynamic pages using same json file.Please help me for this issue.

src/data/data.json

{
    "compdata": [{
        "id": 1,
        "title": "FlexBox",
    }, {
        "id": 2,
        "title": "Grid layout",
    }]
}

graphQl query

query MyQuery {
    allJson {
        edges {
            node {
                compdata {
                    id
                    example
                }
            }
        }
    }
}

gatsby-config.js

{
  resolve: `gatsby-transformer-json`,
  options: {
    typeName: `Json`,
  },
},
{
  resolve: `gatsby-source-filesystem`,
  options: {
    path: `${__dirname}/src/data`,
    name: `data`
  },
},

this is my index.js

 export default function Home(data) {
 // const { compdata } = data.dataJson
 // console.log(data);
 const {compdata} = data.allJson.edges.node;
 console.log(compdata);
 return (
  <Layout>
     <h1>Home page</h1>
    <h1>{JSONData.title}</h1>
       <ul>
         {compdata.map((data1, index) => {
          return <li key={`content_item_${index}`}>{data1.example}</li>
          })}
       </ul>
 </Layout>
 )
}

Solution

  • You mixed what I explained in the other answer (How can I get data from a json via GraphQL?).

    • Importing the JSON directly
    • Using GraphQL (via gatsby-transformer-json)

    To create dynamic pages from a JSON (new information), you just need to import the JSON into your gatsby-node.js file, since it's there where the dynamic magic happens:

    const path = require("path")
    import JSONData from "../path/to/your/json/file.json"
    
    exports.createPages = async ({ graphql, actions, reporter }) => {
      const { createPage } = actions
    
      const youtTemplateFile= path.resolve(`src/templates/yourTemplate.js`)
    
      JSONData.compdata.forEach((item) => {
        createPage({
          path: item.title,
          component: youtTemplateFile,
          context: {
             id: item.id,
           },
        })
      })
    }
    

    In this case, you'll be creating dynamic pages (via createPage API) that will use a template (youtTemplateFile). In the snippet above I'm looping through your JSON object to create dynamic pages on the fly.

    The slug for those pages will be the title since path: item.title but you can customize the JSON to add new fields accordingly or treat the title as slug (removing white spaces and lower casing it).

    In this case, I'm using the context API to send the id that will allow you to create custom filtered queries to get the data from each item (if needed).

    The nodes will be created using gatsby-transformer-json plugin so there you'll need to use the GraphiQL playground (localhost:8000/___graphql) to test all the queries.

    Recommended readings: