Nu pot obține un obiect JSON ca răspuns la o cerere Ajax cu wp_ajax
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.

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

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

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ă.
