I have created a recursive function to get all the products in a shop by inserting the cursor of the last node received as the “after” filter of the next query. However, the function always receives the same first set of products and continues in an infinite loop. It appears the “after” filter is not being used to run the query. The query appears to run correctly when run using the GraphiQL app in the shop so it could be that I am doing something wrong.
function _getAllShopProducts({defaultProductFields, fields, products=[], cursor=null}) {
return new Promise((resolve, reject)=>{
const fetchedFields = fields.length ? fields : defaultProductFields;
const fragment = `
fragment productFields on Product {
${fetchedFields.join(' ')}
}
`;
const queryPrefix = `
query getAllShopProducts ($first: Int!, $cursor: String){
products(first: $first, after: $cursor) {
pageInfo {
hasNextPage
}
edges {
cursor
node {
...productFields
}
}
}
}
`;
const first = 250;
const variables = {first, cursor};
const fullQuery = queryPrefix + fragment;
this.ShopifyGQL // prepares the request to the Shopify GraphQL endpoint by setting headers and access code
.send(JSON.stringify({query:fullQuery, variables}))
.then((res)=>{
const edges = res.body.data.products.edges;
cursor = edges[edges.length-1].cursor; // set cursor to last node
let returnedProducts = [];
edges.forEach((edge)=>{
returnedProducts.push(edge.node);
})
// update products list
products = products.concat(returnedProducts);
// if there are no more pages, return the result
const hasNextPage = res.body.data.products.pageInfo.hasNextPage;
if(hasNextPage){
// recurse
return resolve(_getAllShopProducts.bind(this)({defaultProductFields, fields, products, cursor}))
} else {
return resolve(products);
}
})
})
}