Crazy Horse
asked on
How to send data array using jQuery and Ajax
How would I pass an array into the data property of an Ajax request?
I am getting data from a 3rd party API which has categories and sub categories. This is basically how I look at the data:
I want to post that data to WooCommerce
I am getting data from a 3rd party API which has categories and sub categories. This is basically how I look at the data:
jQuery.each(data.Body.Categories, function(index, value) {
console.log('CategoryName: ', value.CategoryName);
jQuery.each(value.SubCategories, function(key, val) {
console.log('Sub-CategoryName: ', val.CategoryName);
});
});
I want to post that data to WooCommerce
jQuery.ajax({
url: myData.root_url + '/wp-json/wc/v3/products/categories/',
type: 'POST',
beforeSend: (xhr) => {
xhr.setRequestHeader('X-WP-Nonce', myData.nonce);
},
data: {
name: // need to send an array of values here eg:. cat1, cat2, cat3 and subcategories
},
})
ASKER
Hi Julian, thanks for that.
I tried it and get a 400 error: name is not of type string
I don't think I can just send 'data' because that itself is a massive array with all sorts of data in it. I just want to get the category name and any subcategory names. To get this from the array before I looped over them I did the below, just to illustrate how you have to dig to get the category names.
I tried it and get a 400 error: name is not of type string
I don't think I can just send 'data' because that itself is a massive array with all sorts of data in it. I just want to get the category name and any subcategory names. To get this from the array before I looped over them I did the below, just to illustrate how you have to dig to get the category names.
console.log(data.Body.Categories[0].CategoryName);
console.log(data.Body.Categories[0].SubCategories[0].CategoryName);
Please post an example of the object
You likely need to "map" of the catgegories
You likely need to "map" of the catgegories
As text please. I am not going to OCR this ;)
ASKER
Ah, sorry!
Is this okay?
Is this okay?
Body:
Categories: Array(7)
0:
Behaviour: 0
CategoryId: 445
CategoryImageUrl: "http://"
CategoryImageUrl2x: "http://"
CategoryImageUrl3x: "http://"
CategoryName: "Brands"
FilterValueId: 7
ProductCount: 1174
RelativePosition: 1
SubCategories: Array(22)
0: {
CategoryId: 1017,
SubCategories: Array(0),
CategoryName: "cat 1",
RelativePosition: 1,
Behaviour: 0,
…
}
1: {
CategoryId: 946,
SubCategories: Array(0),
CategoryName: "cat2",
RelativePosition: 2,
Behaviour: 0,
…
}
2: {
CategoryId: 947,
SubCategories: Array(0),
CategoryName: "cat3",
RelativePosition: 3,
Behaviour: 0,
…
}
Does this work for you?
https://jsfiddle.net/mplungjan/hxwmpa9s/
Please note I renamed the subItem to CategoryId because that was what I could see in your screen shot
https://jsfiddle.net/mplungjan/hxwmpa9s/
let arr = data.Body.Categories.map(item => [item.CategoryName, ...item.SubCategories.map(subItem => subItem.CategoryId)]).flat();
console.log("arr", arr)
Please note I renamed the subItem to CategoryId because that was what I could see in your screen shot
ASKER
Thanks, that is giving me a response but when I try to submit it I get a 400 error.
jQuery.ajax({
url: myData.root_url + '/wp-json/wc/v3/products/categories/',
type: 'POST',
beforeSend: (xhr) => {
xhr.setRequestHeader('X-WP-Nonce', myData.nonce);
},
data: {
name: data.Body.Categories.map(item => [item.CategoryName, ...item.SubCategories.map(subItem => subItem.CategoryId)]).flat()
},
})
ASKER
Getting an error back after trying that. Not super specific though
{"code":"db_insert_error","message":"Could not insert term into the database.","data":{"status":400}}
Better to do it outside
Perhaps you need to stringify it and use dataType: 'json',
let arr = data.Body.Categories.map( item =>
[item.CategoryName,...item.SubCategories.map(subItem => subItem.CategoryName)]
);
console.log("arr",arr)
$.ajax(
data: { name : arr},
Perhaps you need to stringify it and use dataType: 'json',
Can you try by hand?
data: { name: ["cat1","cat2","cat3"] },
ASKER
Sorry, I saw you updated your answer. That gives me a new error. Will try by hand now..
"code":"rest_invalid_param","message":"Invalid parameter(s): name","data":{"status":400,"params":{"name":"name is not of type string."}}}
ASKER
Just tried by hand as well
{"code":"rest_invalid_param","message":"Invalid parameter(s): name","data":{"status":400,"params":{"name":"name is not of type string."}}}
The error is self explanatory - you are sending an array to a service that expects a string.
Your service won't accept this
The original question was how to send an array as part of an AJAX request - which has been answered - you just included it in the outgoing structure.
Your problem is slightly different - your service is expecting data in a particular form and you are not matching that so lets go back to the service and see what is expected there and decide if you need to change your service to accept an array or your request to send a string.
Your service won't accept this
{
name: [a,b,c]
}
It is expecting this{
name: "string value"
}
The original question was how to send an array as part of an AJAX request - which has been answered - you just included it in the outgoing structure.
Your problem is slightly different - your service is expecting data in a particular form and you are not matching that so lets go back to the service and see what is expected there and decide if you need to change your service to accept an array or your request to send a string.
ASKER
Quite right Julian, I thought that perhaps there was something wrong with the data but it just seems strange that woocommrece wouldn't accept an array of category names. So basically it wants you to only add one at a time then if it won't accept the array.
https://woocommerce.github.io/woocommerce-rest-api-docs/#create-a-product-category
https://woocommerce.github.io/woocommerce-rest-api-docs/#create-a-product-category
ASKER
Seems like I just needed to read a bit better. The title was update batches so I ignored it but after looking at it there is a way to create too
data: {
create: [{name: 'cat1'}, {name: 'cat2'}]
},
Yup - the API document says on the input spec
It is expecting them one at a time.
name | string | Category name. |
It is expecting them one at a time.
ASKER
Thanks Michel,
I am not getting any errors now but the categories are still empty which is weird. If I do it manually then it is populating categories so the format is correct now I think.
The array has data in it, so it's not that the data is empty.
I am not getting any errors now but the categories are still empty which is weird. If I do it manually then it is populating categories so the format is correct now I think.
The array has data in it, so it's not that the data is empty.
ASKER
Perhaps the issue is that I am meant to send an array with objects in it but I am sending multiple arrays now?
0: Array(1)
0: {name: "Cat1"}
length: 1
__proto__: Array(0)
1: Array(1)
0: {name: "Cat2"}
length: 1
__proto__: Array(0)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Perhaps the issue is that I am meant to send an array with objects in it but I am sending multiple arrays now?If you are talking about the categories service then the API does not say anything about an array of objects.
Look at the codes samples provided - it is quite clear that Category is a string only
const data = {
name: "Clothing",
image: {
src: "http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_2_front.jpg"
}
};
WooCommerce.post("products/categories", data)
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.log(error.response.data);
});
ASKER
If you look at the batches then this works:
I tested this above and it works
https://woocommerce.github.io/woocommerce-rest-api-docs/?javascript#batch-update-product-categories
create: [{name: 'cat1'}, {name: 'cat2'}]
I tested this above and it works
https://woocommerce.github.io/woocommerce-rest-api-docs/?javascript#batch-update-product-categories
ASKER
@Michel,
The good news is that your code is now inserting all the categories in WooCommerce! The bad news is that the categories aren't nested. I am guessing that is because you flattened them and/or WooCommerce API doesn't cater for inserting nested data, I am not sure.
The good news is that your code is now inserting all the categories in WooCommerce! The bad news is that the categories aren't nested. I am guessing that is because you flattened them and/or WooCommerce API doesn't cater for inserting nested data, I am not sure.
Ah - that is a different API - your question was about the categories API.
Yeah, from your initial question I gathered you wanted a flat array and not a nested one. I can nest it if you find out a way to send it
ASKER
Hmm. Thanks Julian, looks like you have to do something like this:
I will try a hardcoded one...
{ "product_category": { "name": "New Subcategory", "parent": 52 } }'
I will try a hardcoded one...
{ "product_category": { "name": "New Subcategory", "parent": 52 } }'
ASKER
Okay, so this is getting confusing now, haha.
This creates a subcategory for the parent category with ID 574
So, somehow I would have to loop through categories and add them first and then add the subcategories. The thing is though, that parent category is a WooCommerce ID which won't be the same as the category ID from the API. Not sure that this is actually going to work..
This creates a subcategory for the parent category with ID 574
create: [{ "name": "New Subcategory", "parent": 574 } ]
So, somehow I would have to loop through categories and add them first and then add the subcategories. The thing is though, that parent category is a WooCommerce ID which won't be the same as the category ID from the API. Not sure that this is actually going to work..
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks Julian, think I am going to close this question off now so this doesn't get too long. I might ask again if I get to the point where you mentioned I should rather do this with php then trying to do it inside my Ajax request.
If it were up to me, I wouldn't even save the data into WooCommerce. I would just use a frontend framework/library to display the data directly from the API and then use a third party cart system to handle the checkout. Not sure if that would be possible but seems less long winded.
I understand the desire to store the data so that if the API goes down users can still browse the products from the WooCommerce database, but other than that it seems like a lot of unnecessary work.
If it were up to me, I wouldn't even save the data into WooCommerce. I would just use a frontend framework/library to display the data directly from the API and then use a third party cart system to handle the checkout. Not sure if that would be possible but seems less long winded.
I understand the desire to store the data so that if the API goes down users can still browse the products from the WooCommerce database, but other than that it seems like a lot of unnecessary work.
ASKER
Thanks to both of your for you, your assistance is much appreciated.
YW.
Open in new window
This will result in
Open in new window