Reputation:
I want to choose just featured posts (3 posts) from graphql for then show this in my blog page, so I limit query to only three results but in case that I just have one post the site will fail.
Because, I'm using a staticquery for get data, in this case I should to use render attribute in the staticquery component and I can not to use a if block on the attribute and when graphql won't find other posts it gonna fail.
Here the code:
featured-posts.js
import React from "react"
import MiniFeatured from "../components/minifeatured"
import { StaticQuery, Link, graphql } from "gatsby"
const Featured = () => {
return (
<StaticQuery
query={graphql`
query FeaturedBlogsport {
allMarkdownRemark (
limit: 3
sort: {order: DESC, fields: [frontmatter___date]}
filter: {frontmatter: {featured: {eq: true}}}
) {
edges {
node {
frontmatter {
title
description
post_image
}
fields {
slug
}
}
}
}
}
`}
render={data => (
<div className="mainBlogposts">
<div
className="featuredBlogpost"
style={{backgroundImage: `url('${data.allMarkdownRemark.edges[0].node.frontmatter.post_image}')`}}
>
<div className="featuredBlogpostContent">
<Link to={`https://strokequote.co/${data.allMarkdownRemark.edges[0].node.fields.slug}`}>
<h1 className="featuredBlogpostTitle">
{data.allMarkdownRemark.edges[0].node.frontmatter.title}
</h1>
<h6 className="featuredBlogpostAuthor">
{data.allMarkdownRemark.edges[0].node.frontmatter.description}
</h6>
</Link>
</div>
</div>
<div className="minifeaturedBlogpostsContainer">
<MiniFeatured
title={data.allMarkdownRemark.edges[1].node.frontmatter.title}
description={data.allMarkdownRemark.edges[1].node.frontmatter.description}
postImage={data.allMarkdownRemark.edges[1].node.frontmatter.post_image}
slug={data.allMarkdownRemark.edges[1].node.fields.slug}
/>
<MiniFeatured
title={data.allMarkdownRemark.edges[2].node.frontmatter.title}
description={data.allMarkdownRemark.edges[2].node.frontmatter.description}
postImage={data.allMarkdownRemark.edges[2].node.frontmatter.post_image}
slug={data.allMarkdownRemark.edges[2].node.fields.slug}
/>
</div>
</div>
)}
/>
)
}
export default Featured
PDD. Minifeatured are secondary featured posts in other components. PDD 2. Sorry about my English, I'm still learning
Upvotes: 0
Views: 1007
Reputation: 29320
Why do you use a StaticQuery
to achieve this? You can simply do it by using a regular GraphQL query, like:
import { graphql, Link } from 'gatsby';
import React from 'react';
const Featured = ({ data }) => {
return <div>
{data.allMarkdownRemark.edges.map(({ node: post }) => {
return <div className="mainBlogposts">
<div className="featuredBlogpost"
style={{ backgroundImage: `url(${post.frontmatter.post_image})` }}>
<div className="featuredBlogpostContent">
<Link to={`https://strokequote.co/${post.fields.slug}`}>
<h1 className="featuredBlogpostTitle">
{post.frontmatter.title}
</h1>
<h6 className="featuredBlogpostAuthor">
{post.frontmatter.description}
</h6>
</Link>
</div>
</div>
</div>;
})}
</div>;
};
export const AboutMeData = graphql`
query FeaturedBlogsport {
allMarkdownRemark (
limit: 3
sort: {order: DESC, fields: [frontmatter___date]}
filter: {frontmatter: {featured: {eq: true}}}
) {
edges {
node {
frontmatter {
title
description
post_image
}
fields {
slug
}
}
}
}
}
`;
What I've done is simply get all the 3 articles and loop through them, using your HTML structure. I aliased the node
as a post
using a destructuring inside the iterable variable in { node: post }
but ideally, all that bunch of HTML should be another isolated component (it's really huge) and you should pass post
as a prop
to them but for now, it will work.
The snippet above will simply print the amount of post that the query can fetch, no matter if it's 1, 2, or 3.
Besides, it's cleaner than accessing manually each array position ([0]
, [1]
, etc).
Upvotes: 0
Reputation:
I believe that find found a solution. With useStaticQuery
from gatsby I can do something like this:
const Featured = () => {
const { edges } = FeaturedPostsQuery()
return (
<div className="mainBlogposts">
<div
className="featuredBlogpost"
style={{backgroundImage: `url('${edges[0].node.frontmatter.post_image}')`}}
>
<div className="featuredBlogpostContent">
<Link to={`https://strokequote.co/${edges[0].node.fields.slug}`}>
<h1 className="featuredBlogpostTitle">
{edges[0].node.frontmatter.title}
</h1>
<h6 className="featuredBlogpostAuthor">
{edges[0].node.frontmatter.description}
</h6>
</Link>
</div>
</div>
<div className="minifeaturedBlogpostsContainer">
<MiniFeatured
title={edges[1].node.frontmatter.title}
description={edges[1].node.frontmatter.description}
postImage={edges[1].node.frontmatter.post_image}
slug={edges[1].node.fields.slug}
/>
<MiniFeatured
title={edges[2].node.frontmatter.title}
description={edges[2].node.frontmatter.description}
postImage={edges[2].node.frontmatter.post_image}
slug={edges[2].node.fields.slug}
/>
</div>
</div>
)
}
export default Featured
export const FeaturedPostsQuery = () => {
const { allMarkdownRemark } = useStaticQuery(graphql`
query FeaturedBlogsport {
allMarkdownRemark (
limit: 3
sort: {order: DESC, fields: [frontmatter___date]}
filter: {frontmatter: {featured: {eq: true}}}
) {
edges {
node {
frontmatter {
title
description
post_image
}
fields {
slug
}
}
}
}
}
`)
return allMarkdownRemark
}
Upvotes: 1