I have a next.js website that get’s products from Shopify. It was working well until a couple of months ago when the site stopped building on the development server.
When I run the website locally I now get a Cannot read properties of undefined error and the page doesn’t load.
What are likely causes of the issue and how do I go about fixing it?
error - lib/shopify.js (353:31) @ getProductsInCollection
TypeError: Cannot read properties of undefined (reading 'collectionByHandle')
351 | const cursor = response.data.products.edges[num - 1].cursor;
352 |
> 353 | return data.concat(await recursiveCatalog(cursor));
| ^
354 | } else {
355 | return data;
356 | }
This is how I get the data from Shopify
const domain = process.env.SHOPIFY_STORE_DOMAIN
const storefrontAccessToken = process.env.SHOPIFY_STOREFRONT_ACCESSTOKEN
async function ShopifyData(query) {
const URL = `https://${domain}/api/2021-07/graphql.json`
const options = {
endpoint: URL,
method: "POST",
headers: {
"X-Shopify-Storefront-Access-Token": storefrontAccessToken,
"Accept": "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({ query })
}
try {
const data = await fetch(URL, options).then(response => {
return response.json()
})
return data
} catch (error) {
throw new Error("Products not fetched")
}
}
The error seems to occur when I get products from a collection.
export async function getProductsInCollection() {
const query = `
{
collectionByHandle(handle: "frontpage") {
title
products(first: 60) {
edges {
node {
id
title
productType
handle
metafields(first: 2) {
edges {
node {
namespace
key
value
}
}
}
}
}
}
}`
const response = await ShopifyData(query);
const allProducts = response.data.collectionByHandle.products.edges
? response.data.collectionByHandle.products.edges
: [];
return allProducts;
}
export async function recursiveCatalog(cursor = '', initialRequest = true) {
let data;
if (cursor !== '') {
const query = `{
products(after: "${cursor}", first: 250) {
edges {
cursor
node {
id
handle
}
}
pageInfo {
hasNextPage
}
}
}`;
const response = await ShopifyData(query);
data = response.data.products.edges ? response.data.products.edges : [];
if (response.data.products.pageInfo.hasNextPage) {
const num = response.data.products.edges.length;
const cursor = response.data.products.edges[num - 1].cursor;
console.log('Cursor: ', cursor);
return data.concat(await recursiveCatalog(cursor));
} else {
return data;
}
} else {
const query = `{
products(first: 250) {
edges {
cursor
node {
id
handle
}
}
pageInfo {
hasNextPage
}
}
}
`;
const response = await ShopifyData(query);
data = response.data.products.edges ? response.data.products.edges : [];
if (response.data.products.pageInfo.hasNextPage) {
const num = response.data.products.edges.length;
const cursor = response.data.products.edges[num - 1].cursor;
return data.concat(await recursiveCatalog(cursor));
} else {
return data;
}
}
}
2
Answers
First of all,
collectionByHandle
is deprecated and replaced withcollection
.Add a guard to the response where you have used fetch API or Shopify API.
This will be little help to understand that actually data are fetching.
You could try to follow these steps:
Check GraphQL Schema: Make sure your GraphQL queries match Shopify’s
current schema. Shopify may have made changes that affect the
response structure.
Error Handling: Add error handling to your code to handle undefined
objects gracefully. Check if response.data and
response.data.collectionByHandle exist before accessing properties.
Update Queries: If necessary, update your GraphQL queries to match
any changes in the Shopify API schema.
Verify Environment Variables: Ensure your environment variables
(SHOPIFY_STORE_DOMAIN and SHOPIFY_STOREFRONT_ACCESSTOKEN) are
accurate and up to date.