I need to be able to update the line item properties in the cart. The issue I'm having is that two of the properties include a file upload.
As of now the properties that aren't the file upload do update but I'm getting this error {"status":"bad_request","message":"Parameter Missing or Invalid","description":"Required parameter missing or invalid: 'line' or 'id' param is required"}
Here is my code:
function updateCart(id) {
let formElement = document.querySelector('form[action^="/cart/change.js"]');
formData = new FormData(formElement);
formData.set('id', formData.get('product_key'));
return fetch('/cart/change.js', {
credentials: 'same-origin',
method: 'POST',
headers: {
'Accept': 'multipart/form-data',
'X-Requested-With': 'XMLHttpRequest'
},
body: formData,
success: function(){
window.location.reload()
}
}).then(function (response) {
if (response.ok) {
console.log('update cart successfully with:', formData);
} else {
console.log(response);
}
})
};
<div class="edit-prop-container">
<form action="/cart/change.js" method="post" class="update-cart-form" enctype="multipart/form-data">
<input type="hidden" value="{{ line_item.key }}" name="product_key">
{% assign loop_index = forloop.index %}
{% for property in line_item.properties %}
<div class="property-field">
{% assign first_character_in_key = property.first | truncate: 1, '' %}
{% unless first_character_in_key == '_' %}
<label id="{{ line_item.product_id }}-{{ property.first | handleize }}" class="property-label">{{ property.first }}: </label>
{% assign showProp = property.first %}
{% case showProp %}
{% when 'First Logo' %}
<div id="firstLogoPreviewCart" class="logo-preview">
<img id="firstPreviewCart" src="{{ property.last }}" loading="lazy" width="200" height="200"/>
<p id="firstErrorMessageCart"></p>
<input type="hidden" data-name="{{ property.first }}" name="properties[First Logo]" class="propLine update-textarea autosize new-property" id="{{ line_item.product_id }}-{{ property.first | handleize }}-firstLogo firstLogo{{ line_item.product_id }}" value="{{ property.last }}">
</div>
<input type="file" id="firstLogoUploadCart" data-current-value="{{ property.last }}" onchange="firstLogoCartUpload({{ line_item.product_id }})">
{% when 'First Location' %}
<button type="button" class="button" id="showFirstLocationCart" onclick="ShowFirstLocationCart()">Show Locations</button>
<div id="firstLocationCartContainer">
<img src="https://cdn.shopify.com/s/files/1/0580/9602/5772/files/FrontCenter_256x256_crop_center.png?v=1661857523" height="150" width="150" loading="lazy"/>
<img src="https://cdn.shopify.com/s/files/1/0580/9602/5772/files/RightPanel_256x256_crop_center.png?v=1661857523" height="150" width="150" loading="lazy"/>
<img src="https://cdn.shopify.com/s/files/1/0580/9602/5772/files/LeftPanel_256x256_crop_center.png?v=1661857524" height="150" width="150" loading="lazy"/>
</div>
<select name="properties[First Location]" id="{{ line_item.product_id }}-{{ property.first | handleize }}-firstLocation" class="propLine update-textarea autosize new-property" data-current-value="{{ property.last }}" data-name="{{ property.first }}">
{% if property.last == "Front Center"%}
<option selected="selected" value="Front Center" >Front Center</option>
<option value="Right Panel" >Right Panel</option>
<option value="Left Panel" >Left Panel</option>
{% elsif property.last == "Right Panel" %}
<option value="Front Center" >Front Center</option>
<option selected="selected" value="Right Panel" >Right Panel</option>
<option value="Left Panel">Left Panel</option>
{% elsif property.last == "Left Panel" %}
<option value="Front Center" >Front Center</option>
<option value="Right Panel" >Right Panel</option>
<option selected="selected" value="Left Panel" >Left Panel</option>
{% else %}
<option value="Front Center" >Front Center</option>
<option value="Right Panel" >Right Panel</option>
<option value="Left Panel" >Left Panel</option>
{% endif %}
</select>
{% when 'Second Location' %}
<button type="button" class="button" id="showSecondLocationCart" onclick="ShowSecondLocationCart()">Show Locations</button>
<div id="secondLocationCartContainer">
<img id="secondLocationImgCart" src="https://cdn.shopify.com/s/files/1/0580/9602/5772/t/10/assets/secondLogo_Locations.png" height="248" width="400" loading="lazy">
</div>
<select name="properties[Second Location]" id="{{ line_item.product_id }}-{{ property.first | handleize }}-secondLocation" class="propLine update-textarea autosize new-property" data-current-value="{{ property.last }}" data-name="{{ property.first }}">
{% if property.last == "Back Center" %}
<option selected="selected" value="Back Center" >Back Center</option>
<option value="Back Left" >Back Left</option>
<option value="Back Right" >Back Right</option>
<option value="Left Side" >Left Side</option>
<option value="Right Side">Right Side</option>
{% elsif property.last == "Back Left" %}
<option value="Back Center">Back Center</option>
<option selected="selected" value="Back Left" >Back Left</option>
<option value="Back Right" >Back Right</option>
<option value="Left Side" >Left Side</option>
<option value="Right Side" >Right Side</option>
{% elsif property.last == "Back Right" %}
<option value="Back Center" >Back Center</option>
<option value="Back Left" >Back Left</option>
<option selected="selected" value="Back Right">Back Right</option>
<option value="Left Side" >Left Side</option>
<option value="Right Side" >Right Side</option>
{% elsif property.last == "Left Side" %}
<option value="Back Center" >Back Center</option>
<option value="Back Left" >Back Left</option>
<option value="Back Right">Back Right</option>
<option selected="selected" value="Left Side" >Left Side</option>
<option value="Right Side">Right Side</option>
{% elsif property.last == "Right Side" %}
<option value="Back Center" >Back Center</option>
<option value="Back Left" >Back Left</option>
<option value="Back Right" >Back Right</option>
<option value="Left Side" >Left Side</option>
<option selected="selected" value="Right Side">Right Side</option>
{% else %}
<option value="Back Center" >Back Center</option>
<option value="Back Left" >Back Left</option>
<option value="Back Right" >Back Right</option>
<option value="Left Side" >Left Side</option>
<option value="Right Side" >Right Side</option>
{% endif %}
</select>
{% when 'Second Logo' %}
<div id="secondLogoPreviewCart" class="logo-preview">
<img id="secondPreviewCart" src="{{ property.last }}" loading="lazy" width="200" height="200"/>
<p id="firstErrorMessageCart"></p>
</div>
<input type="file" class="propLine update-textarea autosize new-property" id="{{ line_item.product_id }}-{{ property.first | handleize }}-secondLogo" data-current-value="{{ property.last }}" data-name="{{ property.first }}" value="{{ property.last }}" name="properties[Second Logo]">
{% when 'Second Logo Simple Text' %}
<input type="text" class="propLine update-textarea autosize new-property" id="{{ line_item.product_id }}-{{ property.first | handleize }}-secondLogoSimpleText" data-current-value="{{ property.last }}" data-name="{{ property.first }}" value="{{ property.last }}" name="properties[Second Logo Simple Text]">
{% endcase %}
{% endunless %}
</div>
{% endfor %}
<button type="submit" class="property-popup cart-line-item-update button button--primary" title="Save changes" data-index="{{ loop_index }}" onclick="updateCart({{ line_item.id }})">Update</button>
<button type="button" class="property-popup cart-line-item-cancel button button--secondary" title="Cancel" onclick="cancelPropPop({{ line_item.id }})">Cancel</button>
</form>
</div>
If you have a better solution for updating the line item properties with a file upload I'm all ears.