get all products of one category

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:

enter image description here

Leave a Comment