Focusing on managing products, variants, and collections through the API.
I'm using DropZone for uploading file in my app and then after uploading I'm converting the acceptedFiles to base64 string cause my File obj gets missing when submitting the form.
Then on form submit, in the action method I'm doing the following but this is not working. Can anyone help me fix it?
// Fetching the mediaFiles data.
const mediaFiles = formData.mediaFiles;
// Handling Media Files START =========
if(mediaFiles) {
// Finding the files with and without uploaded files
const filesWithUploads = mediaFiles.filter(upload => Object.keys(upload.fileData).length > 0);
const filesWithOutUpload = mediaFiles.filter(upload => Object.keys(upload.fileData).length === 0);
// Array to store the final media urls for the product.
let productImgResouceUrls = [];
// Handing media files without uploads.
if(filesWithOutUpload) {
// Pushing their url's to the productImgResouceUrls array.
filesWithOutUpload.forEach(file => {
productImgResouceUrls.push(file.url);
});
}
// Handle uploaded media files START.
if(filesWithUploads) {
// Array to store the stagedUploadInput for the stagedUploadsCreate mutation
let stagedUploadInput = [];
// Creating the stagedUploadInput for each upload
filesWithUploads.forEach(file => {
stagedUploadInput.push({
filename: file.fileData.fileName,
fileSize: file.fileData.fileSize.toString(),
mimeType: file.fileData.mimeType,
resource: file.fileData.resource,
// resource: "FILE",
httpMethod: "POST",
})
});
// Calling the stagedUploadsCreate mutation
const stagedUploadsCreateReq = await admin.graphql(
`#graphql
mutation stagedUploadsCreate($input: [StagedUploadInput!]!) {
stagedUploadsCreate(input: $input) {
stagedTargets {
url
resourceUrl
parameters {
name
value
}
}
userErrors {
field
message
}
}
}`,
{
variables: {
input: stagedUploadInput,
},
},
);
const stagedUploadsCreateRes = await stagedUploadsCreateReq.json(); // Fetching the mutation response.
// If no errors then proceed with the stagedUploadsCreateRes data.
if(stagedUploadsCreateRes.data.stagedUploadsCreate.userErrors.length === 0) {
// Fetching the main data node
const stagedTargets = stagedUploadsCreateRes.data.stagedUploadsCreate.stagedTargets;
// Handling the file uploads.
const uploadPromises = stagedTargets.map(async (target, index) => {
// Save the target info.
const params = target.parameters;
const url = target.url;
const resourceUrl = target.resourceUrl;
// Generate a form, add the necessary params and append the file.
const form = new FormData();
params.forEach(({name, value}) => {
form.append(name, value);
});
// Add the file to the form
const base64EncodedFile = filesWithUploads[index].fileData.base64StringFile;
const fileName = filesWithUploads[index].fileData.fileName;
const mimeType = filesWithUploads[index].fileData.mimeType;
// Convert the base64 string to File
const decodedFile = base64ToFile(base64EncodedFile, fileName, mimeType);
form.append("file", decodedFile);
const fetchOptions = {
method: 'POST',
headers: {
"Content-Length": filesWithUploads[index].fileData.fileSize + 5000,
'Content-Type': 'multipart/form-data',
},
body: form,
}
// Uploading the file using fetch
const response = await fetch(url, fetchOptions);
// Handle the response
if (!response.ok) {
console.error(`Fetch request for file ${index} failed with status: ${response.status}`);
throw new Error(`Fetch request for file ${index} failed with status: ${response.status}`);
}
// Returning the response.
return response.json();
})
// Create an array to store information about each upload, including the target index
const uploadResults = await Promise.all(uploadPromises.map((promise, index) => ({
promise,
index,
})));
// Iterate over each upload result
uploadResults.forEach(({ promise, index }) => {
promise.then(result => {
result.push(result);
if (result.ok) {
// When success Push this stagedTargets resourceUrl to the productImgResouceUrls array.
productImgResouceUrls.push(stagedTargets[index].resourceUrl)
console.log(`Upload of file ${index + 1} to staged target ${index} was successful.`);
} else {
// The upload failed
console.error(`Upload of file ${index + 1} to staged target ${index} failed with status: ${result.status}`);
}
});
});
} else {
// Handling the mutation errors.
console.error(`Error when creating stagedUploadsCreate. Error: ${stagedUploadsCreateRes.data.stagedUploadsCreate.userErrors}`)
}
} // Handle uploaded media files END.
// return json(productImgResouceUrls);
// Loop over the productImgResouceUrls and create the input for productCreateMedia mutation.
const createMediaInput = productImgResouceUrls.map(url => ({
alt: "Bundle Image",
mediaContentType: "IMAGE",
originalSource: url,
}));
// return json(createMediaInput)
// FIX: Static data
const productId = "gid://shopify/Product/8204421038230";
if(createMediaInput) {
// Uploading the media to the product
const productCreateMediaReq = await admin.graphql(
`#graphql
mutation productCreateMedia($media: [CreateMediaInput!]!, $productId: ID!) {
productCreateMedia(media: $media, productId: $productId) {
media {
id
alt
mediaContentType
status
}
mediaUserErrors {
field
message
}
product {
id
title
}
}
}`,
{
variables: {
media: createMediaInput,
productId: productId,
}
}
)
// Fetching the productCreateMedia Response
const productCreateMediaRes = await productCreateMediaReq.json();
if(productCreateMediaRes.data.productCreateMedia.mediaUserErrors) {
console.log(`Error running productCreateMedia Mutation. Error: ${productCreateMediaRes.data.productCreateMedia.mediaUserErrors}`)
}
}
// Returning the productImgResouceUrls
return json(productImgResouceUrls);
} // // Handling Media Files END =========
Thanks!