Partage
  • Partager sur Facebook
  • Partager sur Twitter

Return d'une fonction JS "undefined" ??

    15 mars 2018 à 9:52:37

    Bonjour,

    Mon problème today, je n'arrive pas à le comprendre ...

    J'ai 4 fonctions JS, 3 fonctions allant récupérer des valeurs précisent, puis les passent dans un AJAX pour en faire une partie de requête SQL, et "return" le retour de l'AJAX. Là tout est ok, mon retour d'AJAX est correct, et quand je "alert()" la réponse, j'ai bien le bon truc.

    Mais, dans ma 4ème fonction qui appel les 3 précédentes, le alert(Reponse) est correct, mais le return Reponse est undefined .. Je ne comprend pas pourquoi :/

    Le code d'un des 3 JS, ici quand j'appel ma fonction, l'alert est correct, mais si j'alert la fonction dans la fonction qui appel cette fonction, l'alert est undefined :/

    xmlhttp1.onreadystatechange=function() 
    	{
    
    		if (xmlhttp1.readyState==4 && xmlhttp1.status==200) 
    		{
    			var Reponse1 = xmlhttp1.responseText;
    			alert(Reponse1);
    			return Reponse1;		
    		}
    	}


    Les alert() undefined justement :

    var ConditionSQLSecteur = FiltreSecteur();
    	var ConditionSQLFonction = FiltreFonction();
    	var ConditionSQLDate = FiltreDate();
    
    	alert(ConditionSQLSecteur);
    	alert(ConditionSQLFonction);
    	alert(ConditionSQLDate);

    Une petite idée de pourquoi ? Je sèche (et je suis pas super expérimenté en JS)

    Merci :)

    -
    Edité par Haidz 15 mars 2018 à 9:52:48

    • Partager sur Facebook
    • Partager sur Twitter
    Quand on me parle de CSS, et qu'on me pose ensuite une question dessus, je réponds toujours par : C'est pas faux.
      15 mars 2018 à 10:00:08

      Je ne comprends pas bien ton problème, avec deux petits extraits comme ça c'est difficile à comprendre. Mais à vue de nez, ça ne serait pas parce que ton second bout de code s'exécute avant que la requête AJAX soit terminée et donc retourne le résultat? Met un console.log dans chaque bout de code, et vois lequel s'exécute en premier.
      • Partager sur Facebook
      • Partager sur Twitter
      /!\ Si je cesse de répondre c'est parce que vous êtes venus poster sans avoir suivi les cours de base sur le sujet. /!\
        15 mars 2018 à 10:03:00

        Désolé c'est pas très clair effectivement.



        Mais je pense que tu as raison, vu que j'ai le alert qui me donne undefined arrive avant le alert qui me donne la valeur, alors que logiquement, il devrait être avant (vu qu'il est dans la fonction appelée).



        Un moyen de "bloquer" l'exécution de la function tant que chaque fonctions appelée n'ont pas finis de s'exécuter ?


        EDIT : Je viens de voir que je dois passer par un callback mais, bordel je pige pas trop l'utilisation .-.

        J'ai ma function mère appeler FiltrerCandidats() qui va appeler trois fonction Filtre..()

        Je dois faire un truc du genre :

         FiltrerCandidats(Filtre1, Filtre2, Filtre3){
        
        //et ici je récup les valeurs de mes fonctions comme ça ? 
        
        var valeur filtre1 = Filtre1()?
        
        }




        Thanks 

        -
        Edité par Haidz 15 mars 2018 à 10:12:07

        • Partager sur Facebook
        • Partager sur Twitter
        Quand on me parle de CSS, et qu'on me pose ensuite une question dessus, je réponds toujours par : C'est pas faux.
          15 mars 2018 à 10:12:18

          Deux solutions :

          • tu n'appelles/exécute la suite du code que dans la fonction appelée quand ta requête a fini
          • tu rends la requête synchrone (mais dans ce cas l'exécution de la fonction JS qui envoie la requête est bloquée jusqu'à la complétion de celle-ci)

          Pour la première solution, c'est de mettre le 2e bout de code dans la fonction de complétion de la requête. Si tu as beaucoup de code, encapsule le dans une fonction. Si tu veux éviter le problème du callback hell (fonction callback imbriquée dans une fonction callback imbriquée dans une fonction callback...), utilise les Promises (exemple de comment rendre une requête XmlHttpRequest "en promise").

          Mais c'est assez vieux et bricolage. Pour tes requêtes HTTP, y'a plus simple aujourd'hui : l'API Fetch ("expérimentale" = pas gérée pareil dans les détails, et oublie sur IE sans polyfill), ou la librairie axios par exemple (y'en a plein d'autres), qui retournent de base une Promise.

          Pour ce qui est de rendre un appel asynchrone synchrone, avec des Promises, c'est très facile: tuto d'utilisation des mot-clefs async/await

          Par contre pour une vieille xmlhttprequest, aucune idée. En bref, avec du code aussi ancien, pas facile de faire ce que tu demandes sans bricoler.

          Edit: une "fonction callback", c'est une fonction qui est "call back" (rappelée) quand quelque chose d'asynchrone est terminé. En gros, tu donnes une fonction, et elle sera appelée quand la requête est finie par exemple:

          funcAAppelerQuandCestFini(paramsQuonMeDonneQuandCestFini) {
              // ici je fais des trucs
          }
          
          
          appelAUneFonctionAsynchrone(param1, param2, funcAAppelerQuandCestFini);

          funcAAppelerQuandCestFini sera appelée quand appelAUneFonctionAsynchrone décidera de l'appeler. Ça permetde dire quoi faire à une fonction quand elle a fini quelque chose par exemple. La documentation d'une fonction demandant un callback dans ses paramètres précise quels paramètres vont être donnés à la fonction callback (généralement une ou deux variables représentant le résultat de la fonction funcAAppelerQuandCestFin)



          -
          Edité par Genroa 15 mars 2018 à 10:16:51

          • Partager sur Facebook
          • Partager sur Twitter
          /!\ Si je cesse de répondre c'est parce que vous êtes venus poster sans avoir suivi les cours de base sur le sujet. /!\
            15 mars 2018 à 10:17:10

            Woua, ça me parait bien plus compliqué que je pensais .-.

            Si j'ai bien compris, je dois rendre les fonctions en "Promise", et le call back est pas utile dans mon cas ? 

            Merci en tout cas !

            • Partager sur Facebook
            • Partager sur Twitter
            Quand on me parle de CSS, et qu'on me pose ensuite une question dessus, je réponds toujours par : C'est pas faux.
              15 mars 2018 à 10:20:34

              Tu peux utiliser un callback oui, c'est juste que avec si peu d'informations à la base j'ai du mal à saisir ce que tu demandes vraiment. Mais en gros, on essaie de ne plus faire les hmlhttprequest à la main de nos jours, parce que c'est la galère (et on utilise l'API Promise qui est devenue le standard pour les actions asynchrones). Mais si tu veux quand même utiliser un callback (ça fonctionne hein), je t'ai écrit dans le Edit du message précédent un exemple de comment ça fonctionne. :)

              -
              Edité par Genroa 15 mars 2018 à 10:21:08

              • Partager sur Facebook
              • Partager sur Twitter
              /!\ Si je cesse de répondre c'est parce que vous êtes venus poster sans avoir suivi les cours de base sur le sujet. /!\
                15 mars 2018 à 10:27:22

                Yep j'ai vu ça merci !

                Enfaite le code est gros et, étant en "professionnalisation" je ne peut pas montrer certaines parties (confidentialité entreprise etc).

                Mais je dois filtrer une listes de candidats, j'ai 3 fonctions qui vont me construire une partie de condition SQL pour, à la fin taper dans la base.

                Donc ma 1ère fonction filtre va me donner un truc comme : (id=2 or id=3 or id=4)

                la deuxième : AND (nom=toto or nom=bernard)

                et la troisième : AND (age=52 or age=63 or age=78)

                Et, dans ma fonction mère, je dois récupérer les bouts de conditions sql, pour créer la requete finale et taper dans ma base :)

                Mais donc en gros, si je comprend, la structure dois etre la suivante :

                function filtre1(filtre2)
                {
                //je fait mon code filtre1
                filtre2(filtre3); //j'utilise ma fonction filtre2
                }
                
                function filtre2(filtre3)
                {
                //je fait mon code filtre2
                filtre3(fonctionmère); //j'utilise ma fonction filtre3
                }
                
                 function filtre3(fonctionmère)
                {
                //je fait mon code filtre3
                fonctionmère(); //j'utilise ma fonctionmère
                }
                
                functionmère{
                //je peut faire ma fonction mère, mais comment je récup les valeurs des fonctions filtre ? .-.
                }

                 Edit : la structure du code était cassé ^^'

                -
                Edité par Haidz 15 mars 2018 à 10:34:31

                • Partager sur Facebook
                • Partager sur Twitter
                Quand on me parle de CSS, et qu'on me pose ensuite une question dessus, je réponds toujours par : C'est pas faux.
                  15 mars 2018 à 10:39:44

                  Alors, c'est que mon avis, mais je pense que tu imbriques une pelletée de fonctions inutilement là.

                  Je m'explique et te propose une autre manière de faire:

                  • conserve dans la page, quelque part, un objet JS contenant l'état actuel des filtres. Un exemple:
                  requestFilterState = {
                      filter1: "Bernard",
                      filter2: "truc",
                      filter3: "bidule"
                  };

                  Avec des valeurs par défaut cohérentes.

                  • crée une fonction qui va générer la requête PHP à partir de l'état de requestFilterState, envoyer la requête, et, dans un callback, va faire les modifications à effectuer une fois la réponse revenue (en gros, si j'ai bien compris, insérer les nouvelles données quelque part à la place des anciennes)
                  • quand un champ HTML représentant un des filtres est modifié, modifie juste le champ associé dans le requestFilterState, puis rappelle la fonction de mise à jour des données (celle créée au point précédent)

                  De cette manière, tu peux envoyer une demande filtrée chaque fois qu'un champ change (ou au clic sur un bouton, à toi de voir), sans imbriquer les appels de fonction.

                  Dernier point : tu ne devrais pas envoyer des bouts de requête SQL, mais directement l'objet requestFilterState. C'est au code PHP coté serveur que revient la responsabilité de générer la requête SQL appropriée. JS ne devrait même pas se préoccuper de comment est récupéré le résultat à partir de l'état des filtres.

                  -
                  Edité par Genroa 15 mars 2018 à 10:40:44

                  • Partager sur Facebook
                  • Partager sur Twitter
                  /!\ Si je cesse de répondre c'est parce que vous êtes venus poster sans avoir suivi les cours de base sur le sujet. /!\
                    15 mars 2018 à 10:52:51

                    Okk, je comprend ce que tu veux dire mais, comme les filtres sont de différents types (principalement des checkboxs, qui sont dynamique, les filtres peuvent etre créés à l'infini, et des type date aussi, fixes par contre)

                    Je suis donc obligé de passé par une fonction js pour, dans un première temps, savoir combien y'a de checkboxs, et ensuite, savoir lesquelles sont coché.

                    Mais, avec ton exemple je peut : 

                    Créer un array contenant les etats de chaques filtres, quand je modifie un filtre, ma fonction va donc vérifier l'état des checkboxs, et appelé en callback la fonction qui va taper dans la base. De ce fait, si je modifie juste le filtre 1, les fonctions filtre 2 et filtre 3 ne serons pas appelé ?

                    Je commence à voir clair dans le truc là !

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Quand on me parle de CSS, et qu'on me pose ensuite une question dessus, je réponds toujours par : C'est pas faux.
                      15 mars 2018 à 10:58:12

                      C'pas un souci ça, tu peux appeler une fonction dès qu'une checkbox change, et celle-ci va aller regarder l'état des autres dans la page avant de définir la nouvelle valeur du filtre dans l'objet qui stocke l'état global des filtres. :)

                      Utilise un objet plutôt qu'un Array, ça va te faciliter la vie, car tu associes un filtre à une valeur. C'est typiquement pas adapté un Array pour ça. Par contre, la valeur d'un filtre peut être un Array, oui.

                      En gros, tu as une fonction par filtre qui modifie un seul filtre puis appelle la fonction de requête. Mais comme l'état actuel de tous les filtres est stocké dans un objet, pas besoin d'appeler les autres fonctions filtre. Chacune ne sert qu'à modifier l'objet contenant l'état des filtres, et la fonction qui requête ne fait son travail qu'à partir de cet objet.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      /!\ Si je cesse de répondre c'est parce que vous êtes venus poster sans avoir suivi les cours de base sur le sujet. /!\
                        15 mars 2018 à 11:03:45

                        Okk nice je vais tester tout ça !

                        Les fonctions de filtre marchent déjà, donc me reste juste à faire l'objet, et la fonction finale qui tape dedans !

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Quand on me parle de CSS, et qu'on me pose ensuite une question dessus, je réponds toujours par : C'est pas faux.
                          15 mars 2018 à 11:08:01

                          L'idée c'est que comme tu gardes en mémoire l'état actuel de chaque filtre (que chacun modifie si l'interface est modifiée), ton code est beaucoup plus simple par la suite. :)
                          • Partager sur Facebook
                          • Partager sur Twitter
                          /!\ Si je cesse de répondre c'est parce que vous êtes venus poster sans avoir suivi les cours de base sur le sujet. /!\
                            15 mars 2018 à 11:18:06

                            Yep, et moins lourd :)

                            Parce que les candidats, la liste va taper dans les 1000+ xD

                            Bon j'ai bien avancé, mais j'ai toujours pas pigé comment lancer la callback par contre.

                            Je met ma fonction finale en paramètre (sans les "()" ) comme j'ai compris sur internet

                            mais à l'intérieur j'essai de l’exécuter mais, comment ? Faut encore que je cherche sur ce point mdr 

                            -
                            Edité par Haidz 15 mars 2018 à 11:19:09

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Quand on me parle de CSS, et qu'on me pose ensuite une question dessus, je réponds toujours par : C'est pas faux.
                              15 mars 2018 à 11:21:25

                              Quand tu lances la requête, la documentation te détaille sous quelles conditions tel callback qu'on lui a donné va être appelé. Il faut lire la doc sur ce point. Ce n'est pas à toi d'exécuter la fonction, car justement tu ne sais pas quand la requête se termine. C'est la fonction au sein de la requête qui va appeler ta fonction callback au bon moment.

                              Généralement, les fonctions qui envoient des requêtes acceptent deux callback, un qui est appelé quand tout s'est terminé avec succès, et un qui est appelé en cas d'erreur.

                              -
                              Edité par Genroa 15 mars 2018 à 11:24:41

                              • Partager sur Facebook
                              • Partager sur Twitter
                              /!\ Si je cesse de répondre c'est parce que vous êtes venus poster sans avoir suivi les cours de base sur le sujet. /!\
                                15 mars 2018 à 11:24:09

                                Je regarde sur le point mais, les gens qui créer les exemples sont perché :o 

                                Edit : au final, j'ai même plus besoin de call back quand on y pense xD

                                à la fin de mes fonctions filtre, après mon retour ajax, j'appel ma fonction mère

                                Mon objet contenant les filtres est déjà valorisé, donc ça marche :D

                                Merci à toi pour l'aide !

                                -
                                Edité par Haidz 15 mars 2018 à 11:38:43

                                • Partager sur Facebook
                                • Partager sur Twitter
                                Quand on me parle de CSS, et qu'on me pose ensuite une question dessus, je réponds toujours par : C'est pas faux.
                                  15 mars 2018 à 11:38:16

                                  La doc en FR est plus claire:

                                  Doc sur ce qu'est une "fonction de rappel" (callback)

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  /!\ Si je cesse de répondre c'est parce que vous êtes venus poster sans avoir suivi les cours de base sur le sujet. /!\
                                    15 mars 2018 à 14:05:10

                                    Tyy
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Quand on me parle de CSS, et qu'on me pose ensuite une question dessus, je réponds toujours par : C'est pas faux.

                                    Return d'une fonction JS "undefined" ??

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                    • Editeur
                                    • Markdown