slt à tous,
je galère sur l'ajax; voici ce que je fais :
un appel ajax qui doit retourner un nombre depuis le controller; bref qqchose de tres simple :
mon appel ajax

     $( "#test" ).click(function() {
      var nombre = 35;
    $.ajax({
        url: "/homes/test/"+nombre,
       type : 'GET',
       dataType : 'json',
       success : function(response, statut){
           var parsed = jQuery.parseJSON(response);

           console.log(parsed);
           alert(parsed.prix);
       }
    });
});

puis mon controller :

    public function test($nombre){
        $this->layout = null ;
        $this->autoRender = false;
            if($this->request->is('ajax')) {
            return json_encode(array('prix'=>$nombre));
            $this->redirect($this->referer());
        }
    }

et a chaque fois le debug de chrome m'affiche une erreur 500 :
GET http://localhost:8888/homes/test/35 500 (Internal Server Error)

vous auriez des idées ?
ps : sur Cake2 cela marchait bien, mais sur Cake 3 ca a l'air plus compliqué...

5 réponses


Xeta
Réponse acceptée

Hello,

Avec Cake3, quand on souhaite faire une requête en AJAX et avoir un résultat en JSON, il y a rien de plus simple à faire. ^^
Le plus compliqué c'est de savoir qu'il existe une clé spéciale appelé _serialize qui s'occupe de tout. http://book.cakephp.org/3.0/fr/views/json-and-xml-views.html#utilisation-des-vues-de-donnees-avec-la-cle-serialize

Donc ca donnera quelque chose comme ça :

//Pour pouvoir utiliser "_serialize", il faut charger le Component "RequestHandler", c'est obligatoire.
public function initialize()
{
    parent::initialize();
    $this->loadComponent('RequestHandler');
}

public function test($nombre) {
    //Si la requête n'est pas une requête AJAX, alors on affiche une erreur 404.
    if (!$this->request->is('ajax')) {
        throw new \Cake\Network\Exception\NotFoundException();
    }

    $json = [];
    $json['nombre'] = 35;

    $this->set(compact('json'));
    $this->set('_serialize', 'json');
}

Tu n'a pas à créer de vue Homes/test.ctp ou Homes/json/test.ctp, et oui c'est ça la magie de _serialize. :)
Puis, le JavaScript :

$("#test").click(function() {
    var nombre = 35;

    $.ajax({
        url: "/homes/test/" + nombre,
        type : 'GET',
        dataType : 'json',
        success : function(response, statut) {
            console.log(response.nombre);
            //Ou
            console.log(response['nombre']);
        }
    });
});

Autre conseil, quand tu fait du JavaScript avec un Framework, ici en l’occurrence Cake3, j’insiste toujours les gens à récupérer l'URL dans l'HTML quand c'est possible.
Imaginons que #test soit l'ID d'un bouton :

<button id="test" data-url="<?= $this->Url->build(['controller' => 'homes', 'action' => 'test', 35]) ?>" ?>

Et le JavaScript :

$("#test").click(function() {
    $.ajax({
        url: $(this).attr("data-url"), //On récupère l'URL directement depuis le bouton
        type : 'GET',
        dataType : 'json',
        success : function(response, statut) {
            console.log(response.nombre);
            //Ou
            console.log(response['nombre']);
        }
    });
});

A quoi ça sert de faire comme ça ? C'est tout simplement que si un jour, pour X ou Y raisons, tu décides de modifier l'URL de la route /homes/test dans ton fichier routes.php, alors tu n'auras pas à modifier le JavaScript, vue qu'il récupère la route dynamiquement.

Salut,

La doc de CakePHP pour les views JSON. :) (Je sais que ça ne résoudra probablement pas ton code, mais il sera plus propre. C'est déjà ça.)

Tu n'as aucun détail sur l'erreur ? Dans le Preview sous Laravel j'ai l'erreur complète qui s'affiche. (Je ne connais pas Cake3 ;) )

alexyon
Auteur

merci car tu m'as qd mm aidé, maintenant j'ai bien un code 200; mais un probleme persiste :

il me retourne un resultat vide car je ne lui indique pas que $nombre (defini dans l'action test) doit être envoyé à Homes/json/index.ctp

controller :

    public function test($nombre){

        $this->layout = null ;
        $this->autoRender = false;

        if($this->request->is('ajax')) {
            $nombre = 35;
            $this->set(compact('nombre'));
            $this->redirect($this->referer());
        }
    }

et dans ma vue Homes/index.ctp

    $.ajax({
        url: "/homes/test/"+nombre,
       type : 'GET',
       dataType : 'json',
       success : function(response, statut){
        alert(response);
       }

    });

});

et j'ai crée un fichier index.ctp dans Homes/json/

<?php echo json_encode(compact('nombre')); ?>

j'ai suivi la doc : http://book.cakephp.org/3.0/fr/views/json-and-xml-views.html#utilisation-d-une-vue-de-donnees-avec-les-fichiers-de-template

alexyon
Auteur

Slt Xeta,
oui j'avais vu dans un précédent post ton conseil sur l'URL, je l'aurai fait juste apres, mais pour les tests je trouvais ca plus simple.
en tt cas merci bcp ça marche.