web-dev-qa-db-fra.com

Comment construire un objet JSON valide pour la réponse ajax d'un composant?

J'ai configuré un appel Ajax dans mon composant.

Je semble avoir reçu l'appel initial, le contrôleur, le modèle de données fonctionne, car lorsque je passe l'appel JavaScript, je le montre dans l'inspecteur de code en réponse:

({"userblock":"none","fileName":"","fileLocat":"","username":null,"type":"current"});

Mais je n'arrive pas à accéder aux données via JavaScript.

function initialise() {

    console.log(" start Ajax Call ");
    jQuery.ajax({
        type: "POST",
        url: 'index.php?option=com_daily&task=ajax.initialisePerson&format=json',

        data: registration,
        success: function(response){
            console.log("back from ajax");// this shows nothing
            console.log("response is "+response[0].userblock);// this shows nothing
            if(response.message !=""){....

Je suppose que je fais quelque chose de stupide mais toute aide serait géniale.

Le code du contrôleur est:

public function ajax()
{
    $user       = JFactory::getUser();
    $jinput     = JFactory::getApplication()->input;
    // Check Token!
    $token      = JSession::getFormToken();
    $call_token = $jinput->get('token', 0, 'ALNUM');
    if($token == $call_token)
    {
        $task = $this->getTask();
        switch($task)
        {
            case 'initialisePerson':
                try
                {
                    $returnRaw = $jinput->get('raw', false, 'BOOLEAN');
                    $viewValue = $jinput->get('view', NULL, 'INT');

                    if($viewValue)
                    {
                        $result = $this->getModel('ajax')->displayDetails($viewValue);
                    }
                    else
                    {
                        $result = false;
                    }
                    if($callback = $jinput->get('callback', null, 'CMD'))
                    {
                        echo $callback . "(".json_encode($result).");";
                    }
                    elseif($returnRaw)
                    {
                        echo json_encode($result);
                    }
                    else
                    {
                        echo "(".json_encode($result).");";
                    }
                }
                catch(Exception $e)
                {
                    if($callback = $jinput->get('callback', null, 'CMD'))
                    {
                        echo $callback."(".json_encode($e).");";
                    }
                    else
                    {
                        echo "(".json_encode($e).");";
                    }
                }
                break;
        }
    }

Cela m'a donc amené au problème:

echo "(".json_encode($e).");";

J'ai utilisé ce code et il devrait être

echo json_encode($result);

Tout fonctionne maintenant.

1
user1616338

Comment avez-vous trouvé les crochets? Le point-virgule est également faux.

Les objets sont livrés avec des accolades et des tableaux avec des crochets. Votre chaîne fonctionnera avec les 2 problèmes corrigés. Les valeurs sont accessibles avec response.userblock, response.fileName ... Il n'y a pas de "message" dans la réponse, vous n'obtiendrez rien.

Vous devriez utiliser la fonction json_encode en PHP. Ce pourrait également être une bonne idée d’attraper les erreurs.

1
Javatasse

En ce qui concerne votre appel ajax au contrôleur générant json, method est le terme le plus moderne plutôt que typedepuis JQuery 1.9

jQuery.ajax({
    method: 'POST',  // method is more modern than type
    url: 'index.php?option=com_daily&task=ajax.initialisePerson&format=json',
    data: registration,
    success: (function (response) { ...

Personnellement, je n'ai pas encore construit de composant utilisant ajax, mais un didacticiel dédié à ce sujet présente une syntaxe plus lisible pour la transmission des paramètres de l'appel ajax.

https://docs.joomla.org/J3.x:Developing_an_MVC_Component/Adding_AJAX



En ce qui concerne votre contrôleur, veillez à ne transmettre que des JSON valides à chaque réponse possible.

Vous avez raison de dire que le fait d'encapsuler votre chaîne JSON dans ( Et ); Rompra la syntaxe de la chaîne, mais vous devez également vérifier vos autres chaînes de réponse. Avec echo $callback . "(".json_encode($result).");";, $callback Rompra également votre chaîne JSON.

Ma recommandation est d'effectuer tout votre traitement conditionnel et de sauvegarder toutes vos données dans une variable $response. (J'ai toujours des données Push dans mon tableau $response En tant qu'éléments associés comme:

if ($condition === true) {
    $response['message'] = "pass";                   // whatever
    $response['data'] = [1,2,3];                     // whatever
} else {
    $response['message'] = "fail";                   // whatever
    $response['error'] = "Syntax Error in X Query";  // whatever
}

Ensuite, je le repasse via une petite fonctionnalité de Joomla qui se termine par un script:

echo new JResponseJson($response);

De cette façon, vos données php sont toujours parfaitement encodées et l'appel d'encodage n'est effectué qu'une fois à la fin.

À présent, lorsque les données sont renvoyées à jQuery en tant que chaîne de réponse, utilisez response = JSON.parse(response); pour convertir la chaîne en quelque chose que javascript peut mâcher. Si mes données de réponse peuvent inclure des éléments facultatifs, je vérifie leur existence avant d'essayer d'y accéder en écrivant une condition in (pour éviter de générer des avertissements).

Voici un avant-goût de cela:

success(function (response) {
    //console.log(JSON.stringify(response));  // see what Joomla generates for you
    response = JSON.parse(response);

    if ("message" in response.data) {
        if (response.data.message == "pass") {
            if ("data" in response.data) {
                console.log(response.data.data);
            } else {
                console.log("uhoh, 'data' element not found in response.data");
            }
        } elseif (response.data.message == "fail") {
            if ("error" in response.data) {
                console.log(response.data.error);
            } else {
                console.log("uhoh, 'error' element not found in response.data");
            }
        } else {
            console.log("Unknown response.data.message value");
        }
    } else {
        console.log("uhoh, 'message' element not found in response.data");
    }
}

Parfois, j’utilise message comme clé d’une valeur que je souhaite afficher dans une zone bootstrap. Parfois, j’utilise alert comme clé d’une valeur Je ne souhaite jamais proposer de codes d'erreur ou de messages d'erreur mysql bruts dans la réponse, si vous souhaitez restituer un élément error, définissez-le suffisamment spécifique pour vous guider, ainsi que vos utilisateurs, En règle générale, les parties malveillantes ne peuvent en tirer des détails utiles, ce qui rend la manipulation des données de votre javascript plus simple et plus intuitive pour les autres programmeurs.

1
mickmackusa