I thought I might ask here as I wasn’t getting any help in the Technical Forums.
Basically I have an API that gives me product data which I format and then use in the graphql to create a product. I need to create the product, add its variants and then the quantity available for each and its price.
I’ve set this up so far but I’m stuck at doing the last part of setting the price for the options and their qty’s
//Preparing the Data
const prepareAmrodProducts = (products) => {
return products.map((product) => {
// Prepare color options
const colorOptions = product.variants.reduce((acc, variant) => {
if (variant.codeColourName && !acc.includes(variant.codeColourName)) {
acc.push(variant.codeColourName);
}
return acc;
}, []);
const sizeOptions = product.variants.reduce((acc, variant) => {
if (variant.codeSizeName && !acc.includes(variant.codeSizeName)) {
acc.push(variant.codeSizeName);
}
return acc;
}, []);
const productOptions = [];
if (colorOptions.length > 0) {
productOptions.push({
name: "Color",
values: colorOptions.map((color) => ({ name: color })),
});
}
if (sizeOptions.length > 0) {
productOptions.push({
name: "Size",
values: sizeOptions.map((size) => ({ name: size })),
});
}
return {
title: product.productName,
bodyHtml: product.description,
vendor: "Amrod",
productType: product.categories[0]?.name || "Default Category",
images: product.images.map((image) => ({
src: image.urls[0]?.url || "Default Image URL",
width: image.urls[0]?.width || 1024,
height: image.urls[0]?.height || 1024,
})),
productOptions: productOptions,
variants: product.variants.map((variant) => ({
price: variant.price || 0,
inventoryManagement: "SHOPIFY",
inventoryPolicy: "DENY",
sku: variant.fullCode,
inventoryQuantity: variant.stock || 0,
options: [
variant.codeColourName || "",
variant.codeSizeName || "",
].filter(Boolean),
})),
};
});
};
And here is how I attempt to create the product:
const createProductBatch = async (productsData) => {
// Product creation mutation
const productCreateMutation = `
mutation CreateProduct($input: ProductInput!, $media: [CreateMediaInput!]) {
productCreate(input: $input, media: $media) {
product {
id
options {
id
name
position
values
optionValues {
id
name
hasVariants
}
}
media(first: 10) {
nodes {
alt
mediaContentType
preview {
status
}
}
}
variants(first: 5) {
nodes {
id
title
selectedOptions {
name
value
}
}
}
metafields(first: 10) {
edges {
node {
type
namespace
key
value
}
}
}
}
userErrors {
field
message
}
}
}
`;
const batchSize = 5;
const delay = 500;
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
let results = [];
for (let i = 0; i < productsData.length; i += batchSize) {
const batch = productsData.slice(i, i + batchSize);
const batchResults = await Promise.all(
batch.map(async (product) => {
//Media
const mediaInput = product.images.map((image) => ({
originalSource: image.src,
alt: image.altText || "",
mediaContentType: "IMAGE",
}));
// Create the product
const productResponse = await shopifyAPI.post(
"",
JSON.stringify({
query: productCreateMutation,
variables: {
input: {
title: product.title,
bodyHtml: product.bodyHtml,
vendor: product.vendor,
productType: product.productType,
metafields: [
{
namespace: "custom",
key: "sync_from_api",
type: "boolean",
value: "true",
},
],
productOptions: product.productOptions,
},
media: mediaInput,
},
})
);
if (!productResponse.data || productResponse.data.errors) {
console.error("GraphQL Error:", productResponse.data.errors);
return null;
}
if (productResponse.data.data.productCreate.userErrors.length > 0) {
console.error(
"User Errors:",
productResponse.data.data.productCreate.userErrors
);
return null;
}
// Product ID to use for creating variants
const productId = productResponse.data.data.productCreate.product.id;
return {
productId: productId,
};
})
);
results = results.concat(batchResults);
await sleep(delay);
}
return results.filter((result) => result !== null);
};
If anyone can give me some guidance on how to complete the last part or if I’m doing this correctly or wrong etc I’d really appreciate it. Even if you have some resource to teach me in an easy manor.