1

I am making a reusable component in a Gatsby blog to go at the end of blog articles which takes the authorName of the article, and renders an 'About the Author' section, pulling the info from the author's bio stored elsewhere on the site.

I have made the component which works when the authorName is hard coded as a string, but I am stuck on how to get the author name from the article component (passed as props.author) into the GraphQl query.

I can confirm that: 1. The prop author is being passed correctly and console logs exactly right 2. The correct bio information and profile image is being pulled from the team bios according to the hard coded string author name

The missing link is to replace the hardcoded author name string with props.author

Thanks in advance for your help; I've reviewed similar questions and can't find the answer.

This is my component:

AboutAuthor.js

import React from "react";
import { StaticQuery, graphql } from "gatsby";
import Img from "gatsby-image";

export default (props) => (
  <div>
    <StaticQuery
      query={graphql`
        query {
          copy: markdownRemark(
            frontmatter: { name: { eq: "need to replace this string with props.author" } }
          ) {
            html
            frontmatter {
              name
              profileImage {
              childImageSharp {
                fluid(maxWidth: 800) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
            }
          }
        }
      `}

      render={data => (
        <React.Fragment>
          <p>Testing Name: {props.author}</p> // testing the author name is passed ok, will be removed
          <Img
            fluid={data.copy.frontmatter.profileImage.childImageSharp.fluid}
            alt=""
          />
          <div>
            <span>
              {data.copy.frontmatter.name}
            </span>
            <div
              dangerouslySetInnerHTML={{ __html: data.copy.html }}
            />
          </div>
        </React.Fragment>
      )}
    />
  </div>
);
2
  • 1
    Adding to ksav's answer, I would make this component 'dumber' and receive postAuthor data from its parent component instead Commented Oct 19, 2019 at 16:23
  • @DerekNguyen thanks for replying, but I don't understand. This component does get postAuthor from its parent component (the post body component). In this case, I'm not looking to render props from the post, but rather use postAuthor to 'search' for the author's bio and render that data. Commented Oct 20, 2019 at 8:02

3 Answers 3

3

Check out the docs for How StaticQuery differs from page query

StaticQuery can do most of the things that page query can, including fragments. The main differences are:

  • page queries can accept variables (via pageContext) but can only be added to page components
  • StaticQuery does not accept variables (hence the name “static”), but can be used in any component, including pages
  • StaticQuery does not work with raw React.createElement calls; please use JSX, e.g. <StaticQuery />
Sign up to request clarification or add additional context in comments.

Comments

0

You can't do string interpolation or anything like that in static queries. The reason being that the static query needs to be known at build time. That's when it's executed. It runs when you're building the site, not when the site is live. That's the static part of not just the StaticQuery, but Gatsby in general. PageQueries may not have the 'static' in them, but they, too, run a build time. The only difference is that they do allow for the use of arguments, be it in a different way than you're trying to do it here.

If this is on some automatically generated page using the createPages API, you should pass some identifier down to the page, which it can then use in a PageQuery to fetch the data. From what I can tell here, this doesn't look like it's your page element. Is this the bottom of the blogpost where you show some details on the author? It looks like you have a separate entity for your authors, and for your blog pages. That's good. One way to pull this off is by making sure you query all necessary information in your PageQuery. If you have the data in your page component, you can simply pass it down to its children. You just need to get all the necessary identifiers to the PageComponent using the context. This is how it's shown in the Gatsby docs:

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  const blogPostTemplate = path.resolve(`src/templates/blog-post.js`)

  return graphql(`
    query loadPagesQuery ($limit: Int!) {
      allMarkdownRemark(limit: $limit) {
        edges {
          node {
            frontmatter {
              slug
            }
          }
        }
      }
    }
  `, { limit: 1000 }).then(result => {
    if (result.errors) {
      throw result.errors
    }

    result.data.allMarkdownRemark.edges.forEach(edge => {
      createPage({
        path: `${edge.node.frontmatter.slug}`,
        component: blogPostTemplate,
        context: {
          // You need the something to query the author by, and something to query
          // the blog post by.
          author: edge.node.frontmatter.authorId, // or whatever you use to identify authors
          slug: edge.node.frontmatter.slug
        },
      })
    })
  })
}

Notice the two variables passed inside the context object. Now inside your page element, you have these two variables that you can pass to your query. The $autorId variable, and the $slug variable. On the blog page you will need the blog post contents, but I'm sure you already have that part taken care of, as well as the author details to show the info on the author. In the PageQuery you can simply ask for two entities. One for the blogpost, the other for the author.

1 Comment

Thanks for the detailed answer @timmysmalls; unfortunately I couldn't get it working but found an alternate method which I have posted. Thanks
0

Thanks to all the above answers; I didn't have success with my limited GraphQL knowledge and at this stage it's not something I want to dive into - I only have one use case for GraphQL.

So I dived into the docs some more and found this: https://www.gatsbyjs.org/docs/gatsby-config/#mapping-node-types which is working perfectly and is very simple to implement and is designed for the exact reason I needed it (blog author bio information).

I regret not finding this earlier and preventing an unnecessary question but I hope this help someone in the future.

Thanks again.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.