For instance, WP_Query is only for fetching standard post data. Additional data by plugins such as WC will not be fetched.
To do a custom query
If you would like to use a custom query, you could use WC_Product_Query
Place the following in theme’s functions.php and save the javascript into a separate php file. The quick test used WC default sample products.
// in theme's functions.php
// before init, no products is prepared if just direct call in functions.php, so to have quick test, need to place inside a init
add_action( 'init', 'ws365398_simple_test' );
function ws365398_simple_test() {
add_action('wp_enqueue_scripts', 'ws365398_enqueue_scripts', 101);
add_action( 'wp_ajax_my_action', 'get_products' );
add_action( 'wp_ajax_nopriv_my_action', 'get_products' );
}
// actions for ajax
function get_products()
{
if( !empty( $_POST['category'] ) ) {
$cat_id = $_POST['category'];
} else {
$cat_id = 19; // default change to yours, in the test case ensure it have something by default
}
$args = array(
'status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => '12',
'tax_query' => array(
'relation' => 'AND', // relation of 2 taxonomy queries
array(
'taxonomy' => 'product_cat',
'field' => 'term_id', //This is optional, as it defaults to 'term_id'
'terms' => $cat_id,
'operator' => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
),
array(
'taxonomy' => 'product_visibility',
'field' => 'slug',
'terms' => 'exclude-from-catalog', // Possibly 'exclude-from-search' too
'operator' => 'NOT IN'
)
)
);
$query = new WC_Product_Query($args);
$products = $query->get_products();
// convert to array data before pushing to json
$product_arr = [];
foreach ($products as $key => $product) {
$product_arr[] = $product->get_data();
}
// echo json_encode($product_arr);
wp_send_json_success( $product_arr ); // with success flag and use directly
wp_die();
}
// enqueue ajax script
function ws365398_enqueue_scripts()
{
wp_enqueue_script('test-custom-scripts', get_theme_file_uri('ws365398-test-ajax.php'), array(), 't' . time(), true);
}
<?php
// ws365398-test-ajax.php
/** Load WordPress Bootstrap */
// change to your path
require_once( '/project/wp-load.php' );
header("Content-type: text/javascript");?>
function test_ajax() {
let myData = {
action: 'my_action',
};
jQuery.post('<?php echo admin_url( 'admin-ajax.php' );?>', myData, function (response) {
if (response.success == true) {
console.log(response);
}
});
}
To test, just prepare the above files with corrected path for your environment.
Run test_ajax()
in browser inspector and you will see something like the following: