Query multiple collections from Shopify in GatsbyJS - graphql

I want to display groups of Shopify products based on what collections they're associated with, using gatsby-source-shopify
Filtering to get all products from one collection as easy as running this query:
const { allShopifyCollection } = useStaticQuery(
graphql`
query {
allShopifyCollection(filter: {id: {in: "Shopify__Collection__Z2lkOi8vc2hvcGlmeS9Db2xsZWN0aW9uLzE3NzAxMjY3MDQ5OA=="}}) {
edges {
node {
products {
title
}
}
}
}
`
)
However it's not possible (to my knowledge) to query multiple times on the same data type in the same component.
What's the preferred way to approach this issue?
Use multiple components that fetches the data for each collection and
pass it to a grid component?
Fetch all collections and filter out each collection?
Another solution?

Can you use query aliases?
const { allShopifyCollection } = useStaticQuery(
graphql`
query {
collection1: allShopifyCollection(filter: {id: {in: "Shopify__Collection__Z2lkOi8vc2hvcGlmeS9Db2xsZWN0aW9uLzE3NzAxMjY3MDQ5OA=="}}) {
edges {
node {
products {
title
}
}
}
}
collection2: allShopifyCollection(filter: {id: {in: "Shopify__Collection__someOtherCollection"}}) {
edges {
node {
products {
title
}
}
}
}
collection3: allShopifyCollection(filter: {id: {in: "Shopify__Collection__yetAnotherCollection"}}) {
edges {
node {
products {
title
}
}
}
}
`
)

Related

Apollo cache update is not reflected on paginated query

I have two components, one of the components creates new items, the other one displays them using an "infinite scroll list". These two components do not have a parent/child relationship and they're not rendered at the same time (they're on different "pages").
I've followed these docs and included the modified object in the mutation of my first component. And I can see the new object in the Apollo cache using dev tools. (Car:<some UUID> gets added in the cache after the mutation runs)
My paginated component is configured with relay style pagination, and the pagination works fine, but when I add a new item it doesn't appear in the list until I refresh the page.
My InMemoryCache looks like this:
...
typePolicies: {
// paginated results
Query: {
fields: {
cars: relayStylePagination()
}
},
CarsResult: {
fields: {
edges: {
// Concatenate the incoming list items with
// the existing list items.
merge(existing = [], incoming) {
return [...existing, ...incoming]
}
}
}
},
PageInfo: {
fields: {
endCursor: {
merge(existing, incoming) {
return incoming
}
}
}
}
}
The mutation looks like this:
${CAR_SUMMARY_FRAGMENT}
mutation CreateCar($name: String!) {
createCar(
input: {
name: $name
}
) {
...CarSummary
}
}
The CreateCar return type is Car
Then my paginated query:
query CarsPaginated($after: Cursor) {
cars(
page: { first: 25, after: $after }
orderBy: { field: CREATE_TIME, direction: DESC }
) {
edges {
node {
...CarSummary
}
}
totalCount
pageInfo {
hasNextPage
endCursor
}
}
}
The CarsPaginated return type is CarsResult:
type CarsResult {
edges: [CarEdge]
pageInfo: PageInfo!
totalCount: Int!
}
type CarEdge {
node: Car
cursor: Cursor!
}
Ideally, I'd like the new item to show up at the top of my items list on the other component.
I've tried to use the "refetchQueries" attribute but the paginated query is not active since the list component is not rendered at that time.
Maybe there's something I need to do in the typePolicies?

Shopify Discounts GraphQL API

I have two queries, one for fetching automatic discounts and other for fetching code discounts of a shopify store.
So is there a way that I can fetch both the discounts on a single query. Also we are letting users search for their discounts by title, so is there any query that returns data based on discount title because I have seen that in products or collections inside the query we can use:
products(first: 10, query: "title:*searched_text*")
These are my queries:
# for code discounts
query_1 = '''
{
codeDiscountNodes (first:10,query:"status:active"){
edges {
node {
id
codeDiscount {
__typename
... on DiscountCodeBxgy {
status
title
}
... on DiscountCodeBasic {
status
title
}
}
}
}
}
}
'''
# for automatic discounts
query_2 = '''
{
automaticDiscountNodes (first: 10) {
edges {
node {
id
automaticDiscount {
__typename
... on DiscountAutomaticBxgy {
status
title
}
... on DiscountAutomaticBasic {
status
title
}
}
}
}
}
}
'''
Welcome to Stack Overflow!
...is there a way that I can fetch both the discounts on a single query?
Yes, and there are two ways to do this:
First, in GraphQL you can bundle queries together into a single string like so:
{
codeDiscountNodes(first:10) {
edges {
node { id }
}
}
automaticDiscountNodes(first:10) {
edges {
node { id }
}
}
}
Results in:
{
"data": {
"codeDiscountNodes": {
"edges": [
{
"node": { "id": "gid://shopify/DiscountCodeNode/10..." }
}
]
},
"automaticDiscountNodes": {
"edges": [
{
"node": { "id": "gid://shopify/DiscountAutomaticNode/10..." }
}
]
}
}
}
Alternatively, the shopify API provides a general discountNodes endpoint which you can use to request all your discounts together.
{
discountNodes(first:10) {
edges {
node {
id
}
}
}
}
This approach is more efficient than combining the two queries (check out the extensions.cost.actualQueryCost for each of these solutions).
...is there any query that returns data based on discount title?
No, it does not appear like this API allows you to search by title. You can find the list of query filter parameters in the documentation..

Attempting to query with graphql where id is

I need to get a query using graphql in strapi/gatsby where id is {id}.
According to the documentation found here you query all like so:
{
allStrapiArticle {
edges {
node {
id
title
content
}
}
}
}
This works and I'm able to query however I'd like to get only one Article where id is {id};
I have tried:
{
allStrapiArticle(id: "4") {
edges {
node {
id
title
content
}
}
}
}
And also:
{
allStrapiArticle {
edges {
node(id: "4") {
id
title
content
}
}
}
}
Both of the above give me an error. Any idea how I can achieve this?
Use:
{
allStrapiArticle(filter: {id: {eq: "4" }}) {
edges {
node {
id
title
content
}
}
}
}
elemMatch filter might be useful for your use case as well.
Check the localhost:8000/___graphql playground to test your queries and filters.
More references:
https://www.gatsbyjs.com/docs/query-filters/
https://www.gatsbyjs.com/docs/graphql-reference/

GraphQL filtering/sorting DatoCMS GatsbyJS

I have the following GraphQL query:
export const query = graphql`
query NewsQuery($slug: String!) {
datoCmsNews(slug: { eq: $slug }) {
id
title
description
slug
meta {
publishedAt
}
cover {
fluid(maxHeight: 530) {
...GatsbyDatoCmsSizes
}
}
}
allDatoCmsNews(sort: { fields: [meta___publishedAt], order: DESC }, limit: 4) {
edges {
node {
id
title
slug
meta {
publishedAt
isValid
status
}
cover {
fluid(maxHeight: 375) {
...GatsbyDatoCmsSizes
}
}
}
}
}
}
`;
On my allDatoCmsNews query how would I go about about sorting/filtering out a News item where a $slug is equal to the current slug? I don't want to show a News item if that news item is currently being viewed. I'm guessing I would have to use neq just struggling with the correct syntax.
Thanks
Pretty trivial using filter:
allDatoCmsNews(sort: { fields: [meta___publishedAt], order: DESC }, limit: 4, filter: {slug: {ne: $slug}})

Sorting GraphQL query on multiple queries in Gatsby

I'm using Gatsby as my static generator and Contentful as my datasource.
We've got multiple contentTypes in Contentful (blog, event, whitepaper) and I want to return these in within one query and sorted by createdAt date. So far I have the following which returns each contentType in order of each contentType but not in order of date overall.
Is there a way I can do a sort across the entire query?
{
whitepapers: allContentfulWhitepaper(sort: { order: DESC, fields: createdAt }) {
edges {
node {
id
slug
title
}
}
}
blogs: allContentfulBlogPost(sort: { order: DESC, fields: createdAt }) {
edges {
node {
id
slug
title
}
}
}
events: allContentfulEventPage(sort: { order: DESC, fields: createdAt }) {
edges {
node {
id
slug
title
}
}
}
}
I don't think GraphQL query is able to do the sorting across multiple fields, but you can sort in component
import React from 'react';
import { graphql } from 'gatsby';
const IndexPage = ({ data }) => {
const { whitepapers, blogs, events } = data;
const allDataInDesc = [
...whitepagers.edges.map(e => e.node),
...blogs.edges.map(e => e.node),
...events.edges.map(e => e.node),
].sort((a, b) => { return new Date(a.createdAt) > new Date(b.createdAt) ? -1 : 1; });
return <>...</>
}
export const query = graphql`
{
whitepapers: allContentfulWhitepaper(sort: { order: DESC, fields: createdAt }) {
edges {
node {
id
slug
title
createdAt
}
}
}
blogs: allContentfulBlogPost(sort: { order: DESC, fields: createdAt }) {
edges {
node {
id
slug
title
createdAt
}
}
}
events: allContentfulEventPage(sort: { order: DESC, fields: createdAt }) {
edges {
node {
id
slug
title
createdAt
}
}
}
}
`;
export default IndexPage;
Sure you can sort by multiple fields. Just pass fields and sort order as an array to your query:
query MyQuery {
allContentfulPost(
sort: { fields: [featured, updatedAt], order: [ASC, DESC] }) {
edges {
node {
featured
updatedAt(formatString: "d MM yyyy")
}
}
}
}

Resources