Hi Sean,
Yes, I got it to work, but it’s a bit of a workaround (as always!).
For my application, it’s custom sizes of timber, length, width, thickness, where the user can enter the dimensions they want.
So what I’ve ended up doing, is not to use predefined products, instead, when the workflow is as follows:
User enters the width, length, thickness, then clicks “Add to Cart”.
At this point, the API code, creates their item as a unique product, then, once the product is created, it than also adds that product to the cart.
example code:
/*******************************
* Backend code - products.jsw *
*******************************/
import wixStoresBackend from 'wix-stores-backend';
export function createProduct(product) {
return wixStoresBackend.createProduct(product);
}
export function addProductMedia(productId, mediaData) {
return wixStoresBackend.addProductMedia(productId, mediaData);
}
Front End Code:
import { createProduct } from 'backend/products';
import { addProductMedia } from 'backend/products';
function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
}
function updatePrice(){
let price = Number
let totalprice = Number
let costPerSquareMetre = Number
costPerSquareMetre = 0.00
if ($w('#InputThickness').value === "3mm") { costPerSquareMetre = 8.88 }
if ($w('#InputThickness').value === "4mm") { costPerSquareMetre = 10.39 }
if ($w('#InputThickness').value === "6mm") { costPerSquareMetre = 11.82 }
if ($w('#InputThickness').value === "9mm") { costPerSquareMetre = 17.66 }
if ($w('#InputThickness').value === "12mm") { costPerSquareMetre = 20.76 }
if ($w('#InputThickness').value === "15mm") { costPerSquareMetre = 23.98 }
if ($w('#InputThickness').value === "18mm") { costPerSquareMetre = 27.07 }
if ($w('#InputThickness').value === "22mm") { costPerSquareMetre = 35.37 }
if ($w('#InputThickness').value === "25mm") { costPerSquareMetre = 38.46 }
if ($w('#InputThickness').value === "30mm") { costPerSquareMetre = 54.81 }
if ($w('#InputThickness').value === "38mm") { costPerSquareMetre = 62.71 }
price = ((($w('#InputLength').value * $w('#InputWidth').value) / 1000000) * costPerSquareMetre).toFixed(2)
totalprice = (price * $w('#InputQuantity').value).toFixed(2)
$w('#PriceEach').value = '£' + price
$w('#TotalPrice').value = '£' + totalprice
}
export function InputLength_change(event) {
updatePrice()
}
export function InputWidth_change(event) {
updatePrice()
}
export function InputThickness_change(event) {
updatePrice()
}
export function InputQuantity_change(event) {
updatePrice()
}
export function InputQuantity_input(event) {
updatePrice()
}
export function InputLength_input(event) {
updatePrice()
}
export function InputWidth_input(event) {
updatePrice()
}
$w.onReady(function () {
$w("#addToCartButton").onClick(async () => {
let length = $w('#InputLength').value;
let width = $w('#InputWidth').value;
let thickness = $w('#InputThickness').value;
let quantity = $w('#InputQuantity').value;
let price = parseFloat($w('#PriceEach').value.replace('£', ''));
let totalprice = $w('#TotalPrice').value;
const product = {
"name": "Standard MDF",
"description": "<p>Length: " + length + "mm <br>Width: " + width + "mm <br>Thickness: " + thickness + "<br><br>Standard MDF, medium density fibreboard is a popular product for furniture, cabinetry and boxes as it offers a smooth finish and strength. Standard MDF means the product is in its raw state and has not been covered or treated in anyway.</p>",
"price": price,
"productType": "physical"
}
try {
let newProduct = await createProduct(product);
// Product was created...
console.log('Product created...')
// add product to cart
const productId = newProduct._id
const description = newProduct.description
const src = "https://static.wixstatic.com/media/7edb98_b821b1326c0842b5ad93bb4e148e7cf0~mv2.jpg";
const mediaData = [{src}]
console.log(productId)
console.log(description)
sleep(1000);
addProductMedia(productId, mediaData);
console.log('Adding product to cart...')
$w('#shoppingCartIcon1').addToCart(productId, quantity, {
"customTextFields": [ {
"title": "Length",
"value": length + 'mm'
},
{
"title": "Width",
"value": width + 'mm'
},
{
"title": "Thickness",
"value": thickness
},
],
}
)
.then( () => {
console.log("Product added");
} )
.catch( (err) => {
console.log("Product not added to cart:")
console.log(err);
} );
}
catch (err) {
// Product not created!
console.log('Product not created!')
console.log(err)
}
});
})
The above code is the full code for my application but the key elements are define your product, here’s mine using variables for the length and price etc it gets from elsewhere:
const product = {
"name": "Standard MDF",
"description": "<p>Length: " + length + "mm <br>Width: " + width + "mm <br>Thickness: " + thickness + "<br><br>Standard MDF, medium density fibreboard is a popular product for furniture, cabinetry and boxes as it offers a smooth finish and strength. Standard MDF means the product is in its raw state and has not been covered or treated in anyway.</p>",
"price": price,
"productType": "physical"
}
Next create the product and add the product image too:
try {
let newProduct = await createProduct(product);
// Product was created...
console.log('Product created...')
// add product to cart
const productId = newProduct._id
const description = newProduct.description
const src = "https://static.wixstatic.com/media/7edb98_b821b1326c0842b5ad93bb4e148e7cf0~mv2.jpg";
const mediaData = [{src}]
console.log(productId)
console.log(description)
sleep(1000);
addProductMedia(productId, mediaData);
Now that the product is created, add it to the cart, using it’s _ID that was just created:
console.log('Adding product to cart...')
$w('#shoppingCartIcon1').addToCart(productId, quantity, {
"customTextFields": [ {
"title": "Length",
"value": length + 'mm'
},
{
"title": "Width",
"value": width + 'mm'
},
{
"title": "Thickness",
"value": thickness
},
],
}
)
.then( () => {
console.log("Product added");
} )
.catch( (err) => {
console.log("Product not added to cart:")
console.log(err);
} );
}
catch (err) {
// Product not created!
console.log('Product not created!')
console.log(err)
}
});
})
Note that there is a kludge is there!
The sleep 1000! It’s a crude one second delay between the product being created and then it being added to the cart. Without this, it fails and errors with “cannot find product…” as it’s trying to add it as it’s still creating it.
I know a hard coded delay is not the done thing, but I tried to run it synchronous to no avail, no matter what I did, it would still fail. So a brute force delay gets it working for now. Might tidy that up later!
So the plan is:
Create the whole product in code.
Add the image to the code
Wait until the product is added
Add that product to the cart with option custom text
There is one small bug, there’s a slight delay in the correct image appearing in the mini-cart! But it’s only a slight issue, then the true image shows. Again, I think this is to do with it not being created before it’s added.
That’s about it, hope this helps! See how you go!
Cheers,
Andy.