J'ai un problème avec WordPress et Ajax.
Ceci est ma partie JavaScript (je l'ai coupé un peu):
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) );
});
Mon code PHP se présente comme suit:
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' );
Le script obtient la réponse Ajax de admin-ajax. Malheureusement, la console génère une erreur lorsqu'elle parvient à l'instruction each
dans le code JavaScript ... elle dit:
"Uncaught TypeError: Cannot use 'in' operator to search for '4' in Array".
Si je fais un fichier console.log de mes "posts" var, j'obtiens une chaîne "Array". Peu importe comment je passe la variable $list
dans PHP, il retournera toujours une chaîne. La requête renvoie des publications ailleurs, elle n'est donc pas vide. J'ai essayé sans json_encode
, avec et sans déclaration d'en-tête, en utilisant wp_send_json()
, en mettant ob_clean()
avant de faire écho au tableau, de placer le tableau dans un tableau ... Mais il entre toujours dans ajax
car la chaîne Array
et each
ne peut pas le parcourir.
Cela devrait être une chose très simple et je ne comprends pas pourquoi cela ne fonctionne pas. Je n'ai pas d'erreur ou d'avertissement JavaScript ou PHP et tout le reste fonctionne correctement.
La réponse de BODA82 m'a aidé, mais j'ai finalement réalisé que j'aurais dû remplacer la méthode responseText
par la méthode responseJSON
dans mon code JavaScript. Dans l'exemple ci-dessous, je stockais les résultats de la réponse Ajax dans une variable. Je ne savais pas qu'il y avait une méthode spécifique pour obtenir la réponse en JSON. De cette manière, l'objet/tableau avec les résultats get_posts()
est renvoyé correctement et non sous forme de chaîne:
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 à moi-même, mais aussi conseil général: si vous ne pouvez pas réparer quelque chose le soir, c'est un signe que vous devriez aller vous coucher, lire un livre et compter les étoiles. Une réponse sera trouvée le lendemain matin, le plus tôt sera le mieux: D
Il y a un moyen de sortir. Utilisez complete
au lieu de success
ou done
:
posts = $.ajax({
type: 'GET',
url: ajaxurl,
async: false,
dataType: 'json',
data: { action : 'getHotelsList' },
complete: function(results) {
Et essayez de supprimer async:false
si le problème persiste.
Presque là avec votre fonction PHP. Pas besoin de définir l'en-tête. (Edit: aussi, en supposant que get_posts()
renvoie en fait les résultats.)
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' );
Et votre 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.');
}
});