IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Tester la résolution d'une fetch avant démarrage d'une fonction


Sujet :

JavaScript

  1. #1
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 126
    Par défaut Tester la résolution d'une fetch avant démarrage d'une fonction
    Bonjour à tous,

    J'utilise dans mon projet 3 fetch consécutifs :

    Premier fetch : déclenché au choix d'un onglet et qui ramène une portion de formulaire spécifique (boutons et input de dates)
    Deuxième fetch : ramène le data et l'affiche dans la portion du formulaire prévue à cet effet

    Je me trouve confronté au fait que le deuxième fetch n'attend pas que le premier ait fini de s’exécuter ce qui fait bien évidement que les éléments de la page ne sont pas tous disponibles à ce moment précis ... (cas classique ...)
    J'ai pour l'instant détourné le problème en créant un timeout (voir le commentaire : "filtrer au click sur un onglet" dans la fonction "onglets.js") ce qui n'est pas propre et encore moins fiable !

    J'aimerai savoir comment attendre l’exécution du premier fetch et vérifier l'existence des éléments dans la page avant que le deuxième "agenda-semaine.js" ne soit exécuté ...

    J'ai essayé en rajoutant un .then dans le premier fetch puis en le transformant en fonction asynchrone mais je dois louper quelque chose car je n'arrive pas à lier une fonction à l'autre et créer un contrôle d’exécution.

    Je suppose qu'il faut rajouter une fonction callback ?

    Merci d'avance pour votre précieuse aide

    Premier fetch ("onglets.js") :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    const tabContent = document.querySelector(".tabs__content");
    const radButtons = document.querySelectorAll(".tabs__radio");
    export { tabContent, radButtons };
    import { agendaSemaine } from "./agenda-semaine.js";
     
    window.onload = () => {
      const fetchFirstTabUrl = radButtons[0].dataset.url;
     
      //fonction filtre selon l'onglet actif choisi
      const filtrerOnglet = async (url) => {
        let reponse = await fetch(url, {
          method: "POST",
          cache: "no-cache",
          headers: {
            "X-Requested-With": "XMLHttpRequest",
            // "Content-Type": "Application/json",
          },
        })
          .then((response) => response.json())
          .then((data) => {
            tabContent.innerHTML = data.content;
          })
          .catch((error) => alert("Erreur : " + error));
        return reponse;
      };
     
      //Chargement du premier onglet au démarrage
      const url = fetchFirstTabUrl;
      filtrerOnglet(url);
     
      //Filtrer au click sur les onglets
      radButtons.forEach((rb) =>
        rb.addEventListener("change", (e) => {
          const url = e.target.dataset.url;
          filtrerOnglet(url);
          setTimeout(() => {
            if (rb.id === "agenda-semaine") {
              agendaSemaine();
            }
          }, 500);
        })
      );
    };
    Deuxième fetch : (agenda-semaine.js) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    import { tabContent } from "./onglets.js";
     
    export const agendaSemaine = () => {
     
      const inputDebutSemaine = document.querySelector("#inputDebutSemaine");
      const inputFinSemaine = document.querySelector("#inputFinSemaine");
     
      //Recherche des jours pour filtre agenda semaine
      const ajd = new Date();
      const dateDebutSemaineDefaut = new Date(
        ajd.setDate(ajd.getDate() - ajd.getDay() + 1)
      );
     
      //Initialisation des champs date début et fin avec les dates de semaine active
      const dateFinSemaineDefaut = new Date(ajd.setDate(ajd.getDate() + 6));
     
      // inputDebutSemaine.value = "2023-10-01"
      // inputFinSemaine.value = dateFinSemaineDefaut.toISOString().split("T")[0];
     
      // const dateDebutSemaine = new Date(inputDebutSemaine.value)
      //   .toISOString()
      //   .split("T")[0];
     
      // const dateFinSemaine = new Date(inputFinSemaine.value)
      //   .toISOString()
      //   .split("T")[0];
     
      tabContent.addEventListener("change", (e) => {
        let btn = e.target;
     
        if (btn.id === "inputDebutSemaine" || btn.id === "inputFinSemaine") {
          const dateDebutSemaine = inputDebutSemaine.value;
          const dateFinSemaine = inputFinSemaine.value;
          if (dateDebutSemaine.value != null && dateFinSemaine.value != null) {
            rechercherParSemaine(dateDebutSemaine, dateFinSemaine);
          }
        }
      });
      //Initialisation du filtre par semaine (Fetch)
      const rechercherParSemaine = (dateDebutSemaine, dateFinSemaine) => {
     
        const formData = new FormData();
        formData.append("inputDebutSemaine", dateDebutSemaine);
        formData.append("inputFinSemaine", dateFinSemaine);
     
        for (let item of formData) {
          console.log(item[0], item[1]);
        }
     
        const reponse = fetch("/admin/rendez-vous/agenda-semaine-contenu", {
          method: "POST",
          body: formData,
          cache: "no-cache",
          headers: { "X-Requested-With": "XMLHttpRequest" },
        })
          .then((response) => response.json())
          .then((data) => {
            contenuSemaine.innerHTML = data.content;
          })
          .catch((error) => alert("Erreur " + error));
     
        return reponse;
      };
    };
    // rechercherParSemaine(dateDebutSemaine,dateFinSemaine);
     
    // ajd.toLocaleDateString("fr-FR", { month: "long", day: "numeric" });
    // rechercheJour.value = ajd;
    // console.log("Ajd :", ajd);
     
    // const dateActive = rechercheJour.value;
    // console.log(dateActive);

  2. #2
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 505
    Par défaut
    Bonjour,

    Citation Envoyé par clickandgo Voir le message
    J'aimerai savoir comment attendre l’exécution du premier fetch et vérifier l'existence des éléments dans la page avant que le deuxième "agenda-semaine.js" ne soit exécuté ...
    La solution la plus simple c'est de mettre le 2éme fetch dans le then du premier, ou bien utiliser les promesses.

  3. #3
    Membre Expert
    Avatar de Doksuri
    Profil pro
    Développeur Web
    Inscrit en
    Juin 2006
    Messages
    2 491
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 491
    Par défaut
    Citation Envoyé par Toufik83 Voir le message
    La solution la plus simple c'est de mettre le 2éme fetch dans le then du premier, ou bien utiliser les promesses.
    fetch() EST une promesse

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    fetch(1ere_url)
    .then(res => res.json())
    .then(data => {
      //divers verifications
      fetch(2eme_url)
      .then(res => res.json())
      .then(data2 => {
        // suite du traitement
      });
    });
    La forme des pyramides prouve que l'Homme a toujours tendance a en faire de moins en moins.

    Venez discuter sur le Chat de Développez !

  4. #4
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 652
    Par défaut
    Citation Envoyé par Doksuri Voir le message
    fetch() EST une promesse
    pour aller un peu plus loin, fetch retourne une promesse mais res.fetch() aussi, ce qui permet d'enchainer les 2 "then". donc avec un 2e fetch on peut faire l'enchainement suivant :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    fetch(1er_passage)
    .then(res1 => res1.json()) // code résumé de "res1 => {return res1.json();}"
    .then(data1 => {
    	// analyse des données du 1er fetch
    	// ...
    	return fetch(2e_passage);
    })
    .then(res2 => res2.json()) // res2 est le résultat de la résolution du 2e fetch
    .then(data2 => { // data2 est le résultat de la résolution de "res2.json()"
    	// analyse des données du 2er fetch
    	// ...
    })

    donc votre code peut s'organiser comme cela :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    const agendaSemaine = () => {
     
    	const inputDebutSemaine = document.querySelector("#inputDebutSemaine");
    	const inputFinSemaine = document.querySelector("#inputFinSemaine");
     
    	//Recherche des jours pour filtre agenda semaine
    	const ajd = new Date();
    	const dateDebutSemaineDefaut = new Date(
    		ajd.setDate(ajd.getDate() - ajd.getDay() + 1)
    	);
     
    	const formData = new FormData();
    	formData.append("inputDebutSemaine", dateDebutSemaine);
    	formData.append("inputFinSemaine", dateFinSemaine);
     
    	for (let item of formData) {
    		console.log(item[0], item[1]);
    	}
     
    	return reponse = fetch("/admin/rendez-vous/agenda-semaine-contenu", {
    		method: "POST",
    		body: formData,
    		cache: "no-cache",
    		headers: { "X-Requested-With": "XMLHttpRequest" },
    	});
     
     
    };// agendaSemaine()
     
     
    //fonction filtre selon l'onglet actif choisi
    const filtrerOnglet = (url) => {
     
    	fetch(url, {
    		method: "POST",
    		cache: "no-cache",
    		headers: {
    			"X-Requested-With": "XMLHttpRequest",
    			// "Content-Type": "Application/json",
    		},
    	})
    	.then(response => response.json())
    	.then(data => {
    		tabContent.innerHTML = data.content;
    		return agendaSemaine();
    	})
    	.then(res2 => res2.json()) // résultat de l'url "agenda-semaine-contenu"
    	.then(data2 => {
    		contenuSemaine.innerHTML = data.content;
    	})
    	.catch((error) => alert("Erreur : " + error));
     
    };// filtrerOnglet(url)
     
     
    window.onload = () => {
      const fetchFirstTabUrl = radButtons[0].dataset.url;
     
      //Chargement du premier onglet au démarrage
      const url = fetchFirstTabUrl;
      filtrerOnglet(url);
     
      //Filtrer au click sur les onglets
      radButtons.forEach((rb) =>
        rb.addEventListener("change", (e) => {
          const url = e.target.dataset.url;
          filtrerOnglet(url);
        })
      );
    };

  5. #5
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 126
    Par défaut
    Merci à tous pour vos réponses

    Malheureusement j'ai dû mal m'exprimer, je n'ai pas de problème avec l'imbrication/ chaînage de réponses et de différents fetch, ce que voudrais savoir c'est comment :

    Pouvoir obtenir le retour du fetch numéro 1 depuis n'importe quelle fonction ou autre fetch, en effet, je voudrais laisser le fetch de la fonction "onglets.js" qui ramène le contenu des différents onglets tel quel et sans imbrications d'autres fetch dans les .then successifs pour rendre la fonction générique et réutilisable partout dans le projet...

    Le but serait de faire en sorte d'être sûr que le fetch concernant les onglets s'est bien déroulé et que les éléments qu'il retourne soient bien présents dans la page pour ensuite pouvoir lancer d'autres fonctions ou pas suivant le résultat dudit fetch principal...

    J'avais pensé à faire un peu comme dans des fonctions dépendantes c.à.d checker dans la deuxième si la fonction principale renvoie true ou false avant d’exécuter la deuxième fonction,de cette façon je pouvais rendre générique mon fetch concernant les onglets plutôt que de surcharger les promesses...

    En langage humain :

    J'ai une multitude d'onglets dans mon projet qui sont dépendants de la fonction "onglets.js" qui sert à rapatrier les éléments du dom spécifiques à l'onglet actif, je lance ensuite un deuxième fetch ramenant le data de la page suivant l'élément sélectionné ou rempli par l'utilisateur (input, bouton, etc...).
    Idéalement je voudrais avoir un retour sur le bon déroulement du premier fetch en le questionnant depuis n'importe quelle fonction externe pour être sûr qu'il a bien renvoyé du data et des éléments dans la page avant d’exécuter d'autres fonctions ou fetch ramenant le reste du data.

    Excusez la longueur du message ...

  6. #6
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 652
    Par défaut
    si vous voulez savoir si une action est finie vous pouvez utiliser un variable globale (ou quelque chose qui s'en approche suivant votre organisation des fichiers) et stocker un booléen.

    mais je ne comprends pas trop ce que vous allez faire de cette information. si vous avez un code qui se lance, vous testez si les données sont bien reçues. mais ensuite que se passe-t-il si ce n'est pas le cas ? vous arrêtez le code à cet endroit ? vous attendez 2 secondes et revérifiez si les données sont bien reçues ?
    dans ce 2e cas, il vaut mieux que vous exécutez ce code dans le dernier "then" plutot que de faire une boucle de temporisation.

Discussions similaires

  1. Réponses: 13
    Dernier message: 23/02/2018, 16h59
  2. Tester si le mobile est "géolocalisable" avant de lancer une fonction
    Par VTwin dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 08/03/2012, 22h59
  3. comment tester le typed'un champ avant de le changer?
    Par korntex5 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 15/06/2007, 17h52
  4. delai avant execution d'une fonction
    Par dede64 dans le forum ActionScript 1 & ActionScript 2
    Réponses: 2
    Dernier message: 15/01/2007, 11h25
  5. Tester la taille de fichier avant upload
    Par RobinNono dans le forum Général JavaScript
    Réponses: 13
    Dernier message: 27/06/2006, 17h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo