Non riesco a ottenere un oggetto JSON come risposta a una richiesta Ajax con wp_ajax

17 nov 2014, 21:40:47
Visualizzazioni: 309K
Voti: 6

Ho un problema con WordPress e Ajax.

Questa è la mia parte JavaScript (l'ho ridotta un po'):

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

Il mio codice PHP è il seguente:

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

Lo script ottiene la risposta Ajax da admin-ajax. Sfortunatamente la console genera un errore quando arriva all'istruzione each nel codice JavaScript... dice:

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

Se faccio un console.log della mia variabile "posts" ottengo una stringa 'Array'. Non importa come passo la variabile $list in PHP, restituirà sempre una stringa. La query restituisce post altrove, quindi non è vuota. Ho provato senza json_encode, con e senza dichiarazione dell'header, usando wp_send_json(), mettendo ob_clean() prima di fare l'echo dell'array, mettendo l'array dentro un altro array... Ma viene sempre ricevuto in ajax come una stringa Array e each non può ciclare attraverso di essa.

Questa dovrebbe essere una cosa molto semplice e non riesco a capire perché non funziona. Non ho altri errori o avvisi JavaScript o PHP e tutto il resto funziona correttamente.

3
Commenti

Cosa vedi quando vai su http://www.example.com/wp-admin/admin-ajax.php?action=myAjaxFunc

czerspalace czerspalace
17 nov 2014 22:09:37

Qualche progresso sulla tua domanda? Potresti per favore dare un seguito?

kaiser kaiser
15 apr 2015 14:27:11

oh... questa è di 5 mesi fa... Comunque ho risposto alla mia domanda il giorno dopo averla pubblicata, utilizzando parti della risposta di BODA82 - semplicemente non l'ho contrassegnata come risposta corretta; @toscho ha aggiunto il suo seguito molto più tardi ieri e non posso verificare se la sua risposta è valida ora, anche se ha senso

unfulvio unfulvio
17 apr 2015 00:13:46
Tutte le risposte alla domanda 3
0

La risposta di BODA82 ha aiutato, ma alla fine ho capito che avrei dovuto sostituire il metodo responseText con responseJSON nel mio codice JavaScript. Nell'esempio seguente stavo memorizzando i risultati della risposta Ajax in una variabile. Non sapevo che esistesse un metodo specifico per ottenere la risposta in JSON. In questo modo l'oggetto/array con i risultati di get_posts() viene restituito correttamente e non come una stringa:

posts = $.ajax({
    type: 'GET',
    url: ajaxurl,
    async: false,
    dataType: 'json',
    data: { action : 'getHotelsList' },
    done: function(results) {
        // Uhm, forse non ho nemmeno bisogno di questo?
        JSON.parse(results);
        return results;
    },
    fail: function( jqXHR, textStatus, errorThrown ) {
        console.log( 'Impossibile ottenere i post, risposta del server: ' + textStatus + ': ' + errorThrown );
    }
   }).responseJSON; // <-- questo invece di .responseText

Nota per me stesso, ma anche consiglio generale: se non riesci a risolvere qualcosa la sera è un segno che dovresti andare a letto, leggere un libro e contare le stelle. Una risposta si troverà la mattina seguente, quanto prima meglio :D

18 nov 2014 03:50:51
1

Ci siamo quasi con la tua funzione PHP. Non è necessario impostare l'header. (Modifica: Inoltre, assumendo che get_posts() stia effettivamente restituendo risultati.)

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

E il tuo 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.');
    }
});
17 nov 2014 21:57:17
Commenti

Quando salvi dei dati utilizzando JSON.stringify() e poi hai bisogno di leggerli in php. Il seguente codice ha funzionato per me. json_decode( html_entity_decode( stripslashes ($jsonString ) ) );

Vishal Tanna Vishal Tanna
4 dic 2019 09:18:55
0

C'è una via d'uscita. Usa complete invece di success o done:

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

E prova a rimuovere async:false se il problema persiste.

15 apr 2015 14:15:01