Hi
I want to get the products from a specific collection but I am getting following error
bundle.esm.js?74ca:63 Uncaught (in promise) Error: GraphQL error: Variable $id of type ID! was provided invalid value
The strange thing is if I test it via Graphql app from shopify then it works.
Proof:
Don't know what I need to do and I hope someone faced with the same issue and can help me.
My Grapql query looks like this:
export const GET_PRODUCTS_BY_COLLECTION = gql`query ($id: String) {
collection(id: $id) {
products(first: 20) {
edges {
node {
id
title
images(first: 30) {
edges {
node {
id
altText
originalSrc
}
}
}
}
}
}
}
}`
Here is the code of my component:
import { Steps, Button, message, Card, Layout } from 'antd';
import { useQuery } from 'react-apollo';
import React, { useCallback, useEffect, useState } from 'react';
import { GET_ALL_COLLECTIONS, GET_ALL_PRODUCTS, GET_PRODUCTS_BY_COLLECTION } from '../graphql/gql';
import Dropdown from '../Dropdown/Dropdown';
const { Content } = Layout;
const { Meta } = Card;
const { Step } = Steps;
const source = [
{
title: 'All Products',
},
{
title: 'Collection'
}
];
const steps = [
{
title: 'Select Source',
content: 'First-content',
},
{
title: 'Preview',
content: 'Second-content',
},
{
title: 'Last',
content: 'Last-content',
},
];
const Stepper = ({ children }) => {
const [current, setCurrent] = useState(0);
const [activeAllProducts, setactiveAllProducts] = useState(false);
const [activeCollection, setactiveCollection] = useState(false);
const [activeSubCollection, setactiveSubCollection] = useState(false);
const [activeNextButton, setactiveNextButton] = useState(false);
const [collection, setCollection] = useState('');
const [collectionId, setcollectionId] = useState(null);
const productsByCollectionId = useQuery(GET_PRODUCTS_BY_COLLECTION)
console.log(productsByCollectionId)
const res = useQuery(GET_ALL_PRODUCTS, {
variables: {
after: null,
},
});
const { loading, error, data } = useQuery(GET_ALL_COLLECTIONS); //<------------Here is the query
if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;
const collections = [];
let images = [];
const imageNodes = [];
const nodeImages = [];
const { data: data2, fetchMore: fetchMore2 } = res;
if (data2) {
const edgesData = data2.products.edges;
const imageData = [...edgesData];
imageData.forEach((item) => {
images.push(item.node.images);
})
const imageEdges = [...images];
imageEdges.forEach((item) => {
imageNodes.push(item);
})
imageNodes.map((item) => {
item.edges.map((itemSec) => {
nodeImages.push(itemSec.node)
})
})
}
const { edges } = data.collections;
edges.forEach((collection) => {
collections.push(collection.node)
})
const selectedSource = (item) => {
console.log(item)
switch (item) {
case 'All Products':
setactiveAllProducts(true)
setactiveCollection(false);
setactiveNextButton(true);
break;
case 'Collection':
setactiveAllProducts(false)
setactiveNextButton(false);
setactiveCollection(true);
break;
default:
setactiveSubCollection(true);
setactiveNextButton(true);
setCollection(item);
}
};
const next = () => {
setCurrent(current + 1);
if (activeSubCollection) {
const collectionData = data.collections.edges;
const res = collectionData.filter((item) => {
console.log(item.node.title === collection)
return item.node.title === collection;
})
const collectionId = res[0].node.id;
productsByCollectionId.refetch({ <------------Here is the refetch and the variable I pass to graphql
variables: {
id: btoa("gid://shopify/Collection/239930736810")
}
}
)
}
};
const prev = () => {
setCurrent(current - 1);
};
return (
<>
<Steps current={current}>
{steps.map(item => (
<Step key={item.title} title={item.title} />
))}
</Steps>
<div className="steps-content">
<Content>
{(current === 0) ?
<div className="nextEachOther">
<Dropdown data={source} selectedSource={selectedSource} />
{
activeCollection ? <Dropdown data={collections} value={true} selectedSource={selectedSource} /> : null
}
</div>
: null}
{(current === 1) ?
<div>
<div className="nextEachOther" >
{nodeImages.map((item) => {
return (
<Card
hoverable
key={item.id}
style={{ width: 190, margin: 5 }}
cover={<img alt={item.altText} src={item.originalSrc} />}
>
<Meta title={item.altText.substr(0, 20)} />
</Card>
)
})}
{data2.products.pageInfo.hasNextPage ?
<Button type="danger" style={{ width: '100%', margin: 25 }} onClick={() => {
if (data2.products.pageInfo.hasNextPage) {
fetchMore2({
variables: {
after: data2.products.edges[data2.products.edges.length - 1].cursor,
},
updateQuery: (prevResult, { fetchMoreResult }) => {
if (!fetchMoreResult) return prevResult;
fetchMoreResult.products.edges = [
...prevResult.products.edges,
...fetchMoreResult.products.edges,
];
return fetchMoreResult;
},
});
}
}}>
Load more..
</Button> : null}
</div>
</div>
: null}
</Content>
</div>
<div className="steps-action">
{(current < steps.length - 1 && activeNextButton) && (
<Button type="primary" onClick={() => next()}>
Next
</Button>
)}
{current === steps.length - 1 && (
<Button type="primary" onClick={() => message.success('Processing complete!')}>
Done
</Button>
)}
{current > 0 && (
<Button style={{ margin: '0 8px' }} onClick={() => prev()}>
Previous
</Button>
)}
</div>
</>
);
};
export default Stepper;
Hi @Ali_Go,
I believe the issue you're facing is because you're specifying the wrong input type for your GraphQL query in your React code. Note the difference in the type of the input $id
you specify - in GraphiQL it's ID!
but in your React code you specify String
. The error indicates the variable $id
should be of typeID!
Hope this helps.
Best,
Seth.
Hi @syf_
I tried both ways String and ID!.
With ID! within Reacht I am getting an error: The input type is wrong. I am passing it as string or how I can pass the "gid://..." as ID?
Thanks
Ali
User | Count |
---|---|
28 | |
7 | |
7 | |
6 | |
5 |