Nu pot obține un obiect JSON ca răspuns la o cerere Ajax cu wp_ajax

17 nov. 2014, 21:40:47
Vizualizări: 309K
Voturi: 6

Am o problemă cu WordPress și Ajax.

Aceasta este partea mea de JavaScript (am scurtat-o puțin):

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

Codul meu PHP este următorul:

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

Scriptul obține răspunsul Ajax de la admin-ajax. Din păcate, consola aruncă o eroare când ajunge la instrucțiunea each din codul JavaScript... spune:

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

Dacă fac un console.log al variabilei "posts" obțin un string 'Array'. Indiferent cum transmit variabila $list în PHP, va returna întotdeauna un string. Interogarea returnează postări în alte locuri, deci nu este goală. Am încercat fără json_encode, cu și fără declararea header-ului, folosind wp_send_json(), punând ob_clean() înainte de afișarea array-ului, punând array-ul într-un alt array... Dar întotdeauna ajunge în ajax ca un string Array și each nu poate parcurge acest string.

Ar trebui să fie un lucru foarte simplu și nu pot înțelege de ce nu funcționează. Nu am alte erori sau avertismente JavaScript sau PHP și toate celelalte rulează bine.

3
Comentarii

Ce vezi când mergi la http://www.example.com/wp-admin/admin-ajax.php?action=myAjaxFunc

czerspalace czerspalace
17 nov. 2014 22:09:37

Ai făcut vreun progres cu întrebarea ta? Te rog să revii cu un răspuns.

kaiser kaiser
15 apr. 2015 14:27:11

oh... această întrebare este de acum 5 luni... De altfel, am răspuns la propria mea întrebare în ziua următoare după ce am postat-o, folosind fragmente din răspunsul lui BODA82 - doar că nu l-am marcat ca fiind răspunsul corect; @toscho și-a adăugat continuarea mult mai târziu, ieri, nu pot verifica acum dacă răspunsul său este de asemenea bun, deși pare logic

unfulvio unfulvio
17 apr. 2015 00:13:46
Toate răspunsurile la întrebare 3
0

Răspunsul BODA82 a ajutat, dar în cele din urmă mi-am dat seama că ar fi trebuit să înlocuiesc metoda responseText cu responseJSON în codul meu JavaScript. În exemplul de mai jos stocam rezultatele răspunsului Ajax într-o variabilă. Nu știam că există o metodă specifică pentru a obține răspunsul în format JSON. În acest fel, obiectul/matricea cu rezultatele get_posts() este returnată corect și nu ca un șir de caractere:

posts = $.ajax({
    type: 'GET',
    url: ajaxurl,
    async: false,
    dataType: 'json',
    data: { action : 'getHotelsList' },
    done: function(results) {
        // Hmm, poate nici nu am nevoie de asta?
        JSON.parse(results);
        return results;
    },
    fail: function( jqXHR, textStatus, errorThrown ) {
        console.log( 'Nu s-au putut obține postările, răspunsul serverului: ' + textStatus + ': ' + errorThrown );
    }
   }).responseJSON; // <-- aceasta în loc de .responseText

Notă pentru mine, dar și un sfat general: dacă nu poți rezolva ceva seara, este un semn că ar trebui să mergi la culcare, să citești o carte și să numeri stelele. Un răspuns va fi găsit în dimineața următoare, cu cât mai devreme, cu atât mai bine :D

18 nov. 2014 03:50:51
1

Aproape gata cu funcția ta PHP. Nu este nevoie să setezi header-ul. (Editare: De asemenea, presupunând că get_posts() returnează într-adevăr rezultate.)

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

Și JavaScript-ul tău:

$.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('Nu pot recupera datele.');
    }
});
17 nov. 2014 21:57:17
Comentarii

Când salvezi date folosind JSON.stringify() și apoi trebuie să le citești în php. Următorul cod a funcționat pentru mine. json_decode( html_entity_decode( stripslashes ($jsonString ) ) );

Vishal Tanna Vishal Tanna
4 dec. 2019 09:18:55
0

Există o soluție. Folosește complete în loc de success sau done:

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

Și încearcă să elimini async:false dacă problema persistă.

15 apr. 2015 14:15:01