Home > Blockchain >  Fetch only one element from Graphql in Gatsby
Fetch only one element from Graphql in Gatsby

Time:01-04

am new to gatsby and graphql and I came across a tutorial where it is mentioned to fetch all the data using .map. But I want to fetch only one element from the DB. So how do I do it?

import React from "react";
import Layout from "../components/layout";
import { useStaticQuery, graphql, Link } from "gatsby";

const Blogs = () => {
  const data = useStaticQuery(
    graphql`
      query {
        allMarkdownRemark(sort: { frontmatter: { date: ASC } }) {
          edges {
            node {
              frontmatter {
                title
                date(formatString: "DD MM, YYYY")
              }
              excerpt
              id
              fields {
                slug
              }
            }
          }
        }
      }
    `
  );
  return (
    <Layout>
      <ul>
        {data.allMarkdownRemark.edges.map((edge) => {
          return (
            <li key={edge.node.id}>
              <h2>
                <Link to={`/blog/${edge.node.fields.slug}/`}>
                  {edge.node.frontmatter.title}
                </Link>
              </h2>
              <div>
                <span>
                  Posted on {edge.node.frontmatter.date} 
                </span>
              </div>
              <p>{edge.node.excerpt}</p>
              <div>
                <Link to={`/blog/${edge.node.fields.slug}/`}>Read More</Link>
              </div>
            </li>
          );
        })}
      </ul>
    </Layout>
  );
};

export default Blogs;

Lets say I have multiple blogs and I wish to show only a specific one in a page through query like...

query MyQuery {
  markdownRemark((id: {eq: "9ac19d6d"}) //Some ID {
    title
    description
    content
  }
}

How to get this on a page to display? Thanks in advance!

CodePudding user response:

With your query:

query MyQuery {
  markdownRemark((id: {eq: "9ac19d6d"}) //Some ID {
    title
    description
    content
  }
}

Your data will be in data.markdownRemark

You can access those 3 fields directly.

const { title, description, content ] = data.markdownRemark;
return (
  <Layout>
    <div>
      <p>{title}</p>
      <p>{description]</p>
      <p>{content}</p>
    </div>
  </Layout>
)

CodePudding user response:

Depending on what do you want to achieve:

  • If you want just a specific single post. You can filter your useStaticQuery to add the value of the id (if you know it beforehand) like:

    query MyQuery {
       markdownRemark((id: {eq: "123"})  {
         title
         description
         content
       }
    }
    

    useStaticQuery as the name points out, is static and doesn't accept dynamic values.

    Another alternative is to get a specific position from data.allMarkdownRemark to display it.

  • If you are trying to create dynamic posts, hence each post template will display a different blog post (one per template), you need to pass a filter value from gatsby-node.js (where you create the post pages) to the template through Gatsby's context:

      // gatsby-node.js
      posts.forEach(({ node }, index) => {
        createPage({
          path: node.fields.slug,
          component: path.resolve(`./src/templates/blog-post.js`),
          context: {
            id: node.id, 
            title: node.title
          },
        })
      })
    

    Note: here I'm lifting the id and the title. Use whatever works better for you

    Now, you can take advantage of the context in your Blogs component (as long as it's a template):

       const Blogs = ({data}) => {
         console.log("your blog post is:", data)
    
          return (
            <Layout>
              <h1>{data.markdownRemark.title}</h1>    
            </Layout>
          );
        };
    
        export const query = graphql`
          query($id: String!, $title: String!) {
             markdownRemark((id: {eq: $id})  {
               title
               description
               content
             }
          }
        `
    
         export default Blogs;
    

In other words: the first approach uses a static query (via useStaticQuery hook. Static, no dynamic parameters allowed) and the second uses a page query (only available in pages or templates)

  • Related