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") :

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")

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 réponses


You can play skribbl io online for free with people from all over the world. Join to draw the word that was chosen or guess what other players will draw.

bonjour à vous, pour résoudre le problème d'attente du premier fetch avant d'exécuter le deuxième, vous pouvez utiliser les Promesses (Promise). La fonction fetch renvoie une Promesse, et vous pouvez utiliser les méthodes then et catch pour exécuter du code une fois que la Promesse est résolue ou rejetée.

Voici comment vous pouvez modifier votre code pour tirer parti des Promesses :

Premier fetch ("onglets.js") :
javascript
Copy code
const tabContent = document.querySelector(".tabscontent");
const radButtons = document.querySelectorAll(".tabsradio");
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 = (url) => {
return fetch(url, {
method: "POST",
cache: "no-cache",
headers: {
"X-Requested-With": "XMLHttpRequest",
},
})
.then((response) => response.json())
.then((data) => {
tabContent.innerHTML = data.content;
})
.catch((error) => alert("Erreur : " + error));
};

// Chargement du premier onglet au démarrage
const url = fetchFirstTabUrl;

// Utilisation de la Promesse retournée par fetch
filtrerOnglet(url)
.then(() => {
// Une fois le premier fetch terminé, exécutez le deuxième fetch
agendaSemaine();
});

// Filtrer au clic sur les onglets
radButtons.forEach((rb) =>
rb.addEventListener("change", (e) => {
const url = e.target.dataset.url;
filtrerOnglet(url)
.then(() => {
if (rb.id === "agenda-semaine") {
// Une fois le premier fetch terminé, exécutez le deuxième fetch
agendaSemaine();
}
});
})
);
};
Deuxième fetch ("agenda-semaine.js") :
javascript
Copy code
import { tabContent } from "./onglets.js";

export const agendaSemaine = () => {
const inputDebutSemaine = document.querySelector("#inputDebutSemaine");
const inputFinSemaine = document.querySelector("#inputFinSemaine");

// ... (restez inchangé)

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);
}
}
});

// ... (restez inchangé)
};
Avec cette modification, le deuxième fetch (agendaSemaine()) ne sera appelé qu'après que le premier fetch (filtrerOnglet()) soit résolu avec succès. Cela devrait résoudre votre problème d'ordonnancement des opérations asynchrones.