Displaying dynamic JSON data in GatsbyJS
Tags: webdev, gatsby, react, typescript
Published: 2023-04-15 06:40:51

GatsbyJS is an amazing tool to help leverage when building website. GatsbyJS offers amazing features like the built in GraphQL tool to help in queries for files inside the filesystem and retrieve data without the need of reading the data. This is an amazing feature in terms of optimized application performance. GraphQL also offers libraries like ``gatsby-source-dev`` that helps retrieve data from the [Dev.to](dev.to) website.
In a later session, I will show us how to fetch data from dev.to using markdown feature. For today, let us learn how we can use ``gatsby-transform-json`` to retrieve data and display it in our application.

##Prerequisites
* Javascript
* Knowledge with React
* Typescript (But not necessary)
* GatsbyJS (But not necessary)

With this information. Let's dive into it 

We first need to initiialize an new application. Let's go into our terminal and run the following command.
```
$ npm init gatsby
```
This this in your terminal and follow the prompt. I am using the `src` directory because I find it awesome having all files in one folder.
 I am creating my portfolio website and I want to display the list of projects I have done in my projects page.

```
$ cd my-portfolio
$ npm run develop 
```
This spins up a server in ``localhost:8000`` and a Graphql server at ``localhost:8000/__graphql``

I had already set up my project before. Just create a folder inside the `src` and name it `projects`. Then add a folder called `images` inside and a file called ***`products.json`***. When you create a new gatsby project, it comes with some default plugins contained in the ***`gatsby-config.ts`*** file. Let's take a look at it

![Image of Gatsby-config.ts file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bsaz64bdvtd0gxmmfdu6.png)
When you Query for the site's metadata, it is returns the title and siteurl, but we will not look at that.
Inside the plugins' array, there are default plugins like  ``"gatsby-plugin-mdx"``, ``gatsby-plugin-sharp"``, ``"gatsby-transformer-sharp"`` that comes preinstalled.
But for us, we will need to interact with our ``json`` data. So we need to add a few new plugin called `gatsby-transformer-remark` and `gatsby-transformer-json`. These libraries help us interact with the  `JSON` data.
Go to your terminal and run the following

```
$ npm install gatsby-transformer-remark gatsby-transformer-json
```
Once installed, add this to your ***`gatsby-config.ts`*** file.

![GatsbyJS image with transformer-json added](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6u2qflbke82e65vy5dc2.png)
Now we are all set. But there's one more thing to add. We need to give our GraphQL server permission to access the ``projects`` folder we created. So lets do that. Inside our ***`gatsby-config.ts`***, add the following 
```
{
    resolve: 'gatsby-source-filesystem',
    options: {
      "name": "projects",
      "path": "./src/projects/"
    },
    __key: "projects"
  },
```
Now, it can access the ``projects`` folder. Your code should be like this

![Updated with Projects folder view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28d9l0dwnfy529vviz77.png)

Now, let's add a files inside the projects folder called ``projects.json`` and will store our projects information, let's add some info. Let's also create a file called ``images`` inside the projects folder. We will store images for our projects here.
``projects/images``

``src/projects/projects.json``
```

[
    {
        "title":"Project 1",
        "description":"My first project",
        "imageUrl":"./images/image1.png",
        "url":"https://example.com/image1.png"
    },
    {
        "title":"Project 2",
        "description":"My second project",
        "imageUrl":"./images/image2.png",
        "url":"https://example.com/image2.png"
    },
]
```
With this in set, let's go on and start working on our code.

Go to the terminal and spin up your development server
```
$ npm run develop
```
GatsbyJS spins up a development server at ``localhost:8000`` where you can view your app. GatsbyJS also offers a GraphQL playground where you can interact with your files in your projects, this is amazing because it helps interact with files and at the same times Gatsby offers other plugin libraries e.g ``gatsby-source-dev``and ``gatsby-source-hashnode`` which helps fetch from [Dev.to](dev.to) and [Hashnode](hashnode.com), API to fetch for blog posts, but these two are just to name a few, you can search for all plugins

To view your GraphQL playground go to ``localhost:8000/___graphql``

When you visit through this url, you find a nice graphql playground. With this playground, you can query for information and files in your folder, this is amazing.

![Image for GraphQL Playground](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lsf1fwcsqa5grm1rhfz3.png)

You will also see ``allProjectsJson``, this of course depends on what you named your json file, but with this, you can query for information in your json file. I will be adding a file called ``projects.tsx`` in my application. This will be the route for my application's projects page.

Now let's query for some stuff 


![Json file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ablngjvis1epb5q4ddty.png)

We've just query for the information in our file. When we type in the query, we get some information.

![Information Query](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vfl47n1313a6c1tvbkoa.png)
Let's now add this to our project's file.
Go to your ``projects.tsx`` file and write this

```
import * as React from "react"
import { HeadFC, PageProps, useStaticQuery, graphql } from "gatsby"
import ProjectsList from "../components/Projects/Projects.component";
import Footer from "../components/Footer/Footer.component";
const IndexPage: React.FC<PageProps> = () => {
    const data = useStaticQuery(graphql`
        query MyQuery {
        allProjectsJson {
            edges {
                node {
                    id
                    title
                    description
                    url
                    imageUrl {
                        childImageSharp {
                            fluid(maxWidth: 700) {
                                srcSet
                                src
                                base64
                                aspectRatio
                                sizes
                            }
                        }
                    }
                }
            }
        }
    }
    `)
    console.log(data);
    return (
        <Layout>
            <PageInfoComponent title="Projects" path="projects"/>
            <ProjectsList
                projects={data.allProjectsJson.edges}
            />
            <Footer/>
        </Layout>
    )
}

export default IndexPage

export const Head: HeadFC = () => <title>Projects </title>

```
Now in our ``Projects.component.tsx`` file, let's add the following line of code.
So here, Loop through the information provided and display them here.
```
import React from 'react';
import styled from 'styled-components';
import Image from 'gatsby-image';


type ProjectsListProps = {
    projects: any[],
};
function ProjectsList({projects, theme}: ProjectsListProps) {
    return (
        <>
            {
                projects.map((edge: any) => (
                    <div 
                       key={edge.node.id}>
                        <h1>{edge.node.title}</h1> 
                        <Image fluid={edge.node.imageUrl.childImageSharp.fluid} alt={edge.node.title} />
                        <p style={{
                            color: theme?.color
                        }}>
                            {edge.node.description}
                        </p>
                        <a href={edge.node.url}>Learn More </a>
                    </div>
                ))
            }
        </>
    );
}
export default ProjectsList;
```

The ``useStaticQuery`` is a hook that is used. The ``graphql`` allows us to query for the information. This is cool. 
You can add your styling there to display the information.