David Essien
David Essien

Reputation: 1633

Gatsby query works in graphql editor but not in react code

I am working on a blog using Gatsby and I am trying to generate pages based on that tag a user clicks on.

When a user clicks on a tag, he should be redirected to a page that displays a list of articles with that tag.

I created a query that does that. However, my GraphQL query works in my GraphQL editor but not in my react code. It returns an empty array in the code but the expected result when I run the query in the Graphql editor.

import React from "react"
import ArticleCard from "../articleCard/ArticleCard"
import Pagination from "../pagination/Pagination"

import articlesStyles from "./Articles.module.scss"
import { useStaticQuery, graphql } from "gatsby"

const Articles = ({ pageTitle }) => {
  const blogPosts = useStaticQuery(graphql`
    query($tag: String) {
      allMarkdownRemark(
        sort: { order: DESC, fields: [frontmatter___publish_date] },
        filter: { frontmatter: { tags: { in: [$tag] } } }
      ) {
        nodes {
          frontmatter {
            title
            publish_date
            imageUrl
            author
            category
          }
          fields {
            slug
          }
          excerpt(pruneLength: 100)
        }
      }
    }
  `)

  const nodes = blogPosts.allMarkdownRemark.nodes;
  console.log(nodes)
  return (
    <div className={articlesStyles.contentArea}>
      <h1 className={articlesStyles.headerTitle}>{pageTitle}</h1>
      <div className={articlesStyles.articles}>
        {nodes.map(node => {
          return (
            <ArticleCard
              key={node.id}
              {...node.frontmatter}
              excerpt={node.excerpt}
              slug={node.fields.slug}
            />
          )
        })}
      </div>
      <Pagination />
    </div>
  )
}

export default Articles

enter image description here

Upvotes: 1

Views: 568

Answers (2)

EliteRaceElephant
EliteRaceElephant

Reputation: 8162

As @xadm and @ksav noted in their comments:

"Known Limitations useStaticQuery does not accept variables"

Here as a workaround

Query for all blogs, then use Array.prototype.filter() to get the one you need:

// ...
  const blogPosts = useStaticQuery(graphql`
    query {
      allMarkdownRemark(
        sort: { order: DESC, fields: [frontmatter___publish_date] }
        // you can't filter here
      ) {
        nodes {
          frontmatter {
            title
            publish_date
            imageUrl
            author
            category
          }
          fields {
            slug
          }
          excerpt(pruneLength: 100)
        }
      }
    }
  `)

// Get all blogs
const { blogPosts: { allMarkdownRemark: { edges } } } = props;

// filter the blogs
const yourFilteredTag = edges.filter(
  el => el.node.childMarkdownRemark.frontmatter.tag === yourTagVariable);

// Now you can get the filtered list of blogs
console.log(yourFilteredTag);

// ...

Edit

As @Albert Skibinski mentioned this solution is not scalable. The context in gatsby-node.js might be a better solution in your use case.

The Array.prototype.filter() solution I described should be reserved for components where the context variable is not available and you can make sure that the size of the array does not grow excedeedingly large.

Upvotes: 1

Albert Skibinski
Albert Skibinski

Reputation: 499

As mentioned in the comments, you can't use variables in a staticQuery.

However, this may change in the future as many people stumble upon this limitation and there is work in progress to provide 'dynamicQueries'.

In the meanwhile you can use variables in queries in gatsby-node.js and the templates used by the createPage API. So, in your case, you could generate all the pages for all the tags in gatsby-node.js and still use the same article.js as component template.

See: https://www.gatsbyjs.org/docs/adding-tags-and-categories-to-blog-posts/

Upvotes: 1

Related Questions