Re: How does the ajax Fetch API work in Dawn? Issues with FormData & adding multiple products

How does the ajax Fetch API work in Dawn? Issues with FormData & adding multiple products

ed_codes
Shopify Partner
13 0 7

Hey everyone, 

 

I'm trying to add an upsell section on the product page in Dawn - one click should add 3 products. The liquid part is easy, but I'm stuck on the ajax.  

 

I've seen a few tutorials on using Fetch like this one and was able to replicate that method, but it seems this isn't the method used in Dawn, and I wanted to understand how Dawn does it, and have a more seamless integration.

 

For the Add to Cart button, Dawn uses the FormData API and passes the product ID with a hidden input. Why can't I do this with multiple items also? E.g. - 

 

<input type="hidden" name="items" value="{id:41643147788484,quantity:1},{id:41643131044036,quantity:1},{id:41572158046404,quantity:1}">

 

 

Another thing I tried is to pass the items list in product-form.js, under the line where formData is defined. 

 

let items = [
  {id:41643147788484,quantity:1},
  {id:41643131044036,quantity:1},
  {id:41572158046404,quantity:1}
]
const formData = new FormData(this.form);
formData.append('items', JSON.stringify(items))

 

 

Neither of these work, I'm getting a 400 error and the error message is  "must be a collection of items: items

 

Do I even need to use stringify in FormData API? My payload in chrome inspector seems ok.

 

Any advice? Thanks!

 

Replies 4 (4)

Savior
Shopify Partner
537 108 161

You have a create a JSON of all the products and then send it with fetch /add API.

 

You can contact me if you need help in setting up the upsell products.

banned

Juan_Mingo
Shopify Partner
6 0 0

Any luck with this? looks like multiple items cannot be sent with FormData 😕

Nick_Arvanitas
Shopify Partner
2 0 1

Couldn't get it to work with FormData. Doesn't look like items works for it. 

Did get it to work with json though. 

Had to change the fetchConfig() to json and setup the appropriate body. Something important is to make sure you're using variant.ids and not product.ids or you'll get a 404 error on the request. 

MaxDesign
Shopify Partner
215 15 92

If you want to go through a native form submit, your html would look like this:

 

<input name="items[0][id]" value="123456789" >
<input name="items[0][quantity]" value="1" >
<input name="items[1][id]" value="987654321" >
<input name="items[1][quantity]" value="1" >
<input name="items[1][properties][first prop key]" value="first prop value">
<input name="items[1][properties][second prop key]" value="second prop value">

 

  • Notice how the second product also includes 2 product properties
  • Quantity default to 1, so you might just ommit it sometimes

If you want to go through javascript and submit your data dynamically (with formData API), your code would look like this:

 

const items = [
    {
        "id": "123456789",
        "quantity": 1
    },
    {
        "id": "987654321",
        "quantity": 1,
        "properties": {
            "first prop key": "First prop value",
            "second prop key": "Second prop value"
        }
    },
]
const formData = new FormData();
buildFormData(formData, 'items', items);

function buildFormData(formData, key, data) {
    if (data === Object(data) || Array.isArray(data)) {
      for (const i in data) buildFormData(formData, `${key}[${i}]`, data[i]);
    } else data && formData.append(key, data);
  }

 

buildFormData function is self explanatory. It should output something like this when you log your formData Object, which you can then use in your body request:

 

console.log(Object.fromEntries(formData.entries()))
---
{
    "items[0][id]": "123456789",
    "items[0][quantity]": "1",
    "items[1][id]": "987654321",
    "items[1][quantity]": "1",
    "items[1][properties][first prop key]": "First prop value",
    "items[1][properties][second prop key]": "Second prop value"
}​

 

Reach out to me at admin@maxdesign.expert