it-swarm.com.de

Es kann kein JSON-Objekt als Antwort auf eine Ajax-Anfrage mit wp_ajax abgerufen werden

Ich habe ein Problem mit WordPress und Ajax.

Dies ist mein JavaScript-Teil (ich habe ihn ein wenig gekürzt):

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) );
});

Mein PHP Code lautet wie folgt:

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' );

Das Skript erhält die Ajax-Antwort von admin-ajax. Leider gibt die Konsole einen Fehler aus, wenn sie zur Anweisung each im JavaScript-Code gelangt ... es heißt:

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

Wenn ich eine console.log meiner "posts" var mache, erhalte ich einen String 'Array'. Egal wie ich die Variable $list in PHP übergebe, es wird immer ein String zurückgegeben. Die Abfrage gibt Beiträge an anderer Stelle zurück, ist also nicht leer. Ich habe versucht, ohne json_encode, mit und ohne Header-Deklaration, mit wp_send_json(), ob_clean() zu setzen, bevor ich das Array als Echo empfange, das Array in ein Array setze ... Aber es geht immer in ajax als String Array und each kann nicht durchlaufen.

Dies sollte eine sehr einfache Sache sein und ich kann nicht verstehen, warum es nicht funktioniert. Ich habe kein anderes JavaScript oder PHP Fehler oder Warnungen und alles andere läuft gut.

2
unfulvio

Die Antwort von BODA82 half, aber irgendwann wurde mir klar, dass ich responseText in meinem JavaScript-Code durch responseJSON hätte ersetzen sollen. Im folgenden Beispiel habe ich die Ajax-Antwortergebnisse in einer Variablen gespeichert. Ich wusste nicht, dass es eine bestimmte Methode gibt, um die Antwort in JSON zu erhalten. Auf diese Weise wird das Objekt/Array mit get_posts() Ergebnissen korrekt und nicht als Zeichenfolge zurückgegeben:

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

Hinweis für sich selbst, aber auch allgemeiner Hinweis: Wenn Sie am Abend etwas nicht reparieren können, ist dies ein Zeichen, dass Sie ins Bett gehen, ein Buch lesen und Sterne zählen sollten. Eine Antwort wird am nächsten Morgen gefunden, je früher, desto besser: D

5
unfulvio

Es gibt einen Ausweg. Verwenden Sie complete anstelle von success oder done:

posts = $.ajax({
    type: 'GET',
    url: ajaxurl,
    async: false,
    dataType: 'json',
    data: { action : 'getHotelsList' },
    complete: function(results) {

Versuchen Sie, async:false zu entfernen, wenn das Problem weiterhin besteht.

2
Robot Boy

Fast da mit deiner PHP Funktion. Der Header muss nicht gesetzt werden. (Bearbeiten: Unter der Annahme, dass get_posts() tatsächlich Ergebnisse liefert.)

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 ),
        );
    }
    echo json_encode( $list );
    die;
}
add_action( 'wp_ajax_nopriv_myAjaxFunc', 'myAjaxFunc' );
add_action( 'wp_ajax_myAjaxFunc', 'myAjaxFunc' );

Und dein Javascript:

$.ajax({
    url: "<?php bloginfo('url'); ?>/wp-admin/admin-ajax.php",
    type: "POST",
    data: "action=myAjaxFunc",
    success: function(results) {
        var posts = JSON.parse(results);
        console.log(results);
        $.each(posts, function() {
            $('#someSelect').append( $('<option></option>').text(this.name).val(this.id) );
        });
    },
    error: function() {
        console.log('Cannot retrieve data.');
    }
});
2
BODA82