I'm sending an image attribute file by ajax call. But the post api might be constantly breaking for this. I want to push the file in the image attribute array in the formData & have the successful api call.
My Api form data configuration is as shown in the following image:
When I'm checking the formData image attribute array on Console I'm getting the thing image attributes[]: [object file] as shown in the following image: & my api is constantly failing and showing the following error: Following is the code I'm currently stuck on:
/*NewPost.jsx */
handleSubmit = (event) => {
event.preventDefault();
console.log("Submitting")
let error = this.areThereAnyErrors();
if(!error){
let data = {};
data.description = this.state.description.value || "";
// console.log(this.state.images_attributes);
data.images_attributes = this.state.images_attributes[0] || null;
let brand_string = this.state.brand_ids[0].value;
let brands_list = this.props.auto_complete_details.brand_json;
let selected_brand = brands_list.find(function (brand) {
return brand.brand_name.toLowerCase() == brand_string.toLowerCase();
});
if(selected_brand){
this.state.brand_selected.value = selected_brand.brand_id;
}
if(this.state.brand_selected.value){
data.Brand = this.state.brand_selected.value;
} else {
// console.log(this.state.brand_ids);
data.custom_brand = this.state.brand_ids[0].value;
}
let product_string = this.state.product_ids[0].value;
let product_list = this.props.auto_complete_details.product_json;
let selected_product = product_list.find(function (product) {
return product.product_name.toLowerCase() == product_string.toLowerCase();
});
if(selected_product){
this.state.product_selected.value = selected_product.product_id;
}
if(this.state.product_selected.value){
data.Product = this.state.product_selected.value;
} else {
data.custom_product = this.state.product_ids[0].value;
}
data.Price = this.state.price.value;
this.props.onFormSubmit(data);
}
}
render() {
return(
<form onSubmit={this.handleSubmit}>
<div className={"row description new_post_desc "+error_class}>
<div className="col-md-12 col-xs-12" style={{"paddingRight":"0px"}}>
<textarea id="new_post_desc" name="description" className='new-post-description' placeholder="Share your brand story..." ref={(input) => {this.state.description = input}}/>
</div>
</div>
<div className="description">
<div className="row">
<input id="new_post_image" className={this.state.errors.images_attributes ? "error-input disp_inline": "disp_inline"} type="file" name="image" accept="image/*" ref={(input) => {this.state.images_attributes[0] = input}} />
</div>
<div className="row margin-top-10">
<div className="col-md-2 col-sm-2 col-xs-3 new_post_spacing">
<input id='autocomplete_brand' className={this.state.errors.brand_ids ? 'typeahead error-input new_post_capsules tt-hint hint_user_info' : 'typeahead new_post_capsules hint_user_info'} type="text" name="brand" placeholder="Brand" ref={(input) => {this.state.brand_ids[0] = input}}/>
<input id="brand_value_selected" style={{display: "none"}} value="" ref={(input) => {this.state.brand_selected = input}}/>
</div>
<div className="col-md-2 col-sm-2 col-xs-3 new_post_spacing">
<input id='autocomplete_product' className={this.state.errors.product_ids ? 'typeahead error-input new_post_capsules tt-hint hint_user_info' : 'typeahead new_post_capsules hint_user_info'} type="text" name="product" placeholder="Product" ref={(input) => {this.state.product_ids[0] = input}}/>
<input id="product_value_selected" style={{display: "none"}} value="" ref={(input) => {this.state.product_selected = input}} />
</div>
<div className="col-md-2 col-sm-2 col-xs-3 new_post_spacing">
<input id='autocomplete_price' className={this.state.errors.price ? 'typeahead new_post_capsules tt-hint hint_user_info error-input' : 'typeahead new_post_capsules tt-hint hint_user_info'} type="number" name="price" placeholder="Price" ref={(input) => {this.state.price = input}}/>
</div>
<div className="col-md-2 col-sm-2 col-xs-3 new_post_spacing">
<button type="submit" className="btn button-styling" style={{"outline":"none"}} disabled={this.props.new_post_creation_in_progress}>Share { loading_icon }</button>
</div>
</div>
</div>
<div className="row">
{ this.state.has_errors ? <div className="error_mesg">* Please provide required information</div> : '' }
</div>
</form>
);
}
const mapDispatchToProps = (dispatch, ownProps) => {
var that = this;
return {
dispatch,
onFormSubmit: (data) => {
dispatch(getNewPostDetails(data));
}
};
}
/* Actions/index.js */
export const getNewPostDetails = (data) => {
console.log(data);
var data_value = data;
return function(dispatch) {
var formData = new FormData();
// add assoc key values, this will be posts values
// setting form data
console.log(data_value);
//for image files
if(data_value.images_attributes) {
formData.append('images_attributes[]', $('input[type=file]')[0].files[0]);
}
//for video files
formData.append('video_attributes[]', null);
//for custom brands
if(data_value.custom_brand) {
formData.append('brand_ids[]', data_value.custom_brand);
}
//for products
if(data_value.custom_product) {
formData.append('product_ids[]', data_value.custom_product);
}
//For Price & Description
formData.append('price', data_value.Price);
formData.append('description', data_value.description);
for (let pair of formData.entries()) {
console.log(pair[0] + ': ' + pair[1]);
}
$.ajax({
type: "POST",
url: `${mainurl}/api/v1/posts`,
// headers: checkAuthHeaders(), // the main solution
formData: formData,
beforeSend: function(){
$("#new_post_desc").prop('disabled', true);
$("#autocomplete_brand").prop('disabled', true);
$("#autocomplete_product").prop('disabled', true);
$("#autocomplete_price").prop('disabled', true);
dispatch(createPostProgress(true));
},
success: function(resp) {
$('#new_post_desc').val("");
$('#new_post_image').val("");
$('#autocomplete_brand').val("");
$('#autocomplete_product').val("");
$('#autocomplete_price').val("");
$("#brand_value_selected").val("");
$("#product_value_selected").val("");
$("#new_post_desc").prop('disabled', false);
$("#autocomplete_brand").prop('disabled', false);
$("#autocomplete_product").prop('disabled', false);
$("#autocomplete_price").prop('disabled', false);
dispatch(receiveNewPostDetails(resp));
dispatch(resetNewPostFlag());
dispatch(createPostProgress(false));
},
error: function(error) {
dispatch(createPostProgress(false));
},
async: true,
cache: false,
contentType: false,
processData: false,
timeout: 60000
});
};
}