Can't get a JSON object in response to an Ajax request with wp_ajax

  • I have a problem with WordPress and Ajax.

    This is my JavaScript part (I trimmed it a bit):

    var posts = $.ajax({
        type: 'POST',
        url: ajaxurl,
        async: false,
        dataType: 'json',
        data: { action: 'myAjaxFunc' },
        done: function(response) {
            return response;
        }
    }).responseText;
    
    $.each(posts, function() {
        $('#someSelect').append( $('<option</option>').text(this.name).val(this.id) );
    });
    

    My PHP code is as follows:

    function myAjaxFunc() {
    
        $posts = get_posts( array(
            'posts_per_page'   => -1,
            'orderby'          => 'title',
            'order'            => 'ASC',
            'post_type'        => 'my-post-type',
            'post_status'      => array( 'publish', 'draft' )
        ) );
    
        $list = array();
        foreach ( $posts as $post ) {
            $list[] = array(
                'id'   => $post->ID,
                'name' => $post->post_title,
                'link' => get_permalink( $post->ID ),
            );
        }
    
        header("Content-type: application/json");
        echo json_encode( $list );
        die;
    }
    add_action( 'wp_ajax_nopriv_myAjaxFunc', 'myAjaxFunc' );
    add_action( 'wp_ajax_myAjaxFunc', 'myAjaxFunc' );
    

    The script gets the Ajax response from admin-ajax. Unfortunately the console throws an error when it gets to the each statement in the JavaScript code... it says:

    "Uncaught TypeError: Cannot use 'in' operator to search for '4' in Array".
    

    If I do a console.log of my "posts" var I get a string 'Array'. No matter how I pass the $list variable in PHP it will always return a string. The query returns posts elsewhere, so it's not empty. I tried without json_encode, with and without declaring header, using wp_send_json(), putting ob_clean() before echoing the array, putting the array into an array... But it always gets into ajax as a string Array and each cannot cycle through it.

    This should be a very simple thing and I can't understand why it's not working. I don't have other JavaScript or PHP errors or warnings and everything else runs fine.

    Any progress on your question? Could you please follow up?

    oh... this is from 5 months ago... I did answer to my own question by the way the next day I posted it, using bits of BODA82 answer - I just didn't marked it as the correct answer; @toscho added his follow up much later yesterday I can't verify if his answer is also good now, it makes sense though

  • unfulvio

    unfulvio Correct answer

    6 years ago

    BODA82's answer helped, but eventually I realized that I should have replaced responseText with responseJSON method in my JavaScript code. In the example below I was storing the Ajax response results in a variable. I didn't know there was a specific method to get the response in JSON. In a such way the object/array with get_posts() results is returned correctly and not as a string:

    posts = $.ajax({
        type: 'GET',
        url: ajaxurl,
        async: false,
        dataType: 'json',
        data: { action : 'getHotelsList' },
        done: function(results) {
            // Uhm, maybe I don't even need this?
            JSON.parse(results);
            return results;
        },
        fail: function( jqXHR, textStatus, errorThrown ) {
            console.log( 'Could not get posts, server response: ' + textStatus + ': ' + errorThrown );
        }
       }).responseJSON; // <-- this instead of .responseText
    

    Note to self, but also general advice: if you can't fix something in the evening it's a sign you should go to bed, read a book, and count stars. An answer will be found the next morning, the earlier the better :D

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM