Je rencontre une erreur non récurrente dans l'exploitation du retour du serveur sous forme de tableau json. Comme il est dit à la fin des consignes de cette activité: "Le serveur est utilisé par tous les apprenants OpenClassrooms. La liste des liens varie en fonction de leur activité." Et précisément j'ai eu le cas où un autre utilisateur et moi-même avons envoyé un lien en même temps vers le serveur et celui-ci m'a renvoyé à travers un tableau Json, la donnée correspondant à son lien et non au mien. J'utilise une variable donneesRecues qui stocke le tableau Json renvoyé par le serveur et je selectionne le premier élément du tableau donneesRecues[0]. Or dans le cas présent l'élément [0] correspondait à son lien et le mien à celui "[-1]". Existe-t-il un moyen d'écarter ce type d'erreur? Condition et Comparaison entre donnée entrante et sortante du serveur (auteur et url)? ou autre chose?
Autre problème je cherche à maintenir le nouvel élément crée du DOM correspondant au nouveau lien. J'ai essayé de m'attaquer à sessionStorage, mais soit je m'y prend mal, soit ce n'est pas possible à l'aide de cela mais cela n'a pas fonctionné et je cherche un moyen pour le nouvel élément soit maintenu en cas entre autre de rechargement de la page.
Voici la partie où je rencontre l'erreur :
ajaxGet("https://oc-jswebsrv.herokuapp.com/api/liens", function(reponse){
var donneesRecues = JSON.parse(reponse);
console.log(donneesRecues[0].titre);
console.log(donneesRecues[0].url);
console.log(donneesRecues[0].auteur);
var nouveauLien = {
titre: donneesRecues[0].titre,
url: donneesRecues[0].url,
auteur: donneesRecues[0].auteur
};
var nouveauLienRecu = creerLiensElts(nouveauLien);
var lien = document.getElementsByClassName("lien");
document.getElementById("contenu").insertBefore(nouveauLienRecu, lien[0]);
});
et voici mon code complet
var listeLiens = [
{
titre: "So Foot",
url: "http://sofoot.com",
auteur: "yann.usaille"
},
{
titre: "Guide d'autodéfense numérique",
url: "http://guide.boum.org",
auteur: "paulochon"
},
{
titre: "L'encyclopédie en ligne Wikipedia",
url: "http://Wikipedia.org",
auteur: "annie.zette"
}
];
// On définit une fonction charger de creer les éléments des liens
function creerLiensElts(lien)
{
var blocLiensElts = document.createElement("div");
blocLiensElts.setAttribute("class", "lien");
var titreLiensElts = document.createElement("a");
titreLiensElts.textContent = lien.titre;
titreLiensElts.href = lien.url;
titreLiensElts.style.color = "#428bca";
titreLiensElts.style.textDecoration = "none";
titreLiensElts.style.fontWeight = "bold";
var spanLiensElts = document.createElement("span");
spanLiensElts.textContent = lien.url;
spanLiensElts.style.marginLeft = "0.5%";
var auteurLiensElts = document.createElement("p");
auteurLiensElts.textContent = "Ajouté par " + lien.auteur;
blocLiensElts.appendChild(titreLiensElts);
blocLiensElts.appendChild(spanLiensElts);
blocLiensElts.appendChild(auteurLiensElts);
return blocLiensElts;
}
// On déclare une variable chargée de contenir l'élément du DOM où seront stocké les liens
var contenu = document.getElementById("contenu");
// Une boucle forEach pour parcourir le tableau listeLiens et ajouter les liens dans l'élément du DOM selectionné ci-dessus.
listeLiens.forEach(function (lien){
var lien = creerLiensElts(lien);
contenu.appendChild(lien);
});
// On déclare une variable qui stock un nouvel élément du DOM (div) chargé de stocker le message de confirmation de l'ajout d'un lien.
var contenerConfirmation = document.createElement("div");
contenerConfirmation.id = "contConfirm";
contenerConfirmation.style.marginBottom = "10px";
document.body.insertBefore(contenerConfirmation, contenu);
// On ajoute le boutton qui permet l'ajout d'un lien
var bouttonElt = document.createElement("button");
bouttonElt.id = "nouveauLien";
bouttonElt.textContent = "Ajouter un lien";
bouttonElt.style.marginBottom = "0.5%";
document.querySelector("body").insertBefore(bouttonElt, document.querySelector("div"));
// On gère l'événement click qui permet de faite apparaître le formulaire de création
bouttonElt.addEventListener("click", function(event){
// On crée l'élément du DOM form (pour formulaire)
var formulaire = document.createElement("form");
// On crée l'élément du DOM qui représente le champ input où on entrera le nom de l'auteur du nouveau lien
var auteurNouveauLienElt = document.createElement("input");
auteurNouveauLienElt.setAttribute("type", "text");
auteurNouveauLienElt.id = "auteur";
auteurNouveauLienElt.setAttribute("name", "auteur");
auteurNouveauLienElt.setAttribute("required", "required");
auteurNouveauLienElt.setAttribute("placeholder", "Entrez votre nom");
auteurNouveauLienElt.maxlength = "40";
auteurNouveauLienElt.style.marginBottom = "1%";
auteurNouveauLienElt.style.marginRight = "0.5%";
// On crée l'élément du DOM qui représente le champ input où on entrera le titre du nouveau lien
var titreNouveauLienElt = document.createElement("input");
titreNouveauLienElt.setAttribute("type", "text");
titreNouveauLienElt.id = "titre";
titreNouveauLienElt.setAttribute("name", "titre");
titreNouveauLienElt.setAttribute("required", "required");
titreNouveauLienElt.setAttribute("placeholder", "Entrez le titre du lien");
titreNouveauLienElt.maxlength = "100";
titreNouveauLienElt.style.marginBottom = "1%";
titreNouveauLienElt.style.marginRight = "0.5%";
/* On crée l'élément du DOM qui représente le champ input où on entrera le nom de l'url du nouveau lien.
Nous avons choisi un input de type text (et non url) pour que le http:// ne soit pas obligatoire dès la saisie mais via une regex à la soumission du formulaire.*/
var urlNouveauLienElt = document.createElement("input");
urlNouveauLienElt.setAttribute("type", "text");
urlNouveauLienElt.id = "url";
urlNouveauLienElt.setAttribute("required", "required");
urlNouveauLienElt.setAttribute("name", "url");
urlNouveauLienElt.setAttribute("placeholder", "Entrez l'URL du lien");
urlNouveauLienElt.style.marginBottom = "1%";
urlNouveauLienElt.style.marginRight = "0.5%";
// On crée l'élément du DOM qui représente le champ input qui soumettra le formulaire pour ajout du nouveau lien.
var bouttonAjoutElt = document.createElement("input");
bouttonAjoutElt.value = "Ajouter";
bouttonAjoutElt.setAttribute("type", "submit");
bouttonAjoutElt.style.marginBottom = "1%";
bouttonAjoutElt.style.marginRight = "0.5%";
// On insert dans le DOM les éléments du formulaire crées ci-dessus.
document.querySelector("body").replaceChild(formulaire, document.getElementById("nouveauLien"));
formulaire.appendChild(auteurNouveauLienElt);
formulaire.appendChild(titreNouveauLienElt);
formulaire.appendChild(urlNouveauLienElt);
formulaire.appendChild(bouttonAjoutElt);
// On gère la soumission du formulaire via un événement submit et via des regex pour vérifier la conformité de l'URL.
formulaire.addEventListener("submit", function(event){
var regexUrl = /http:\/\/.+\.(fr|com|net)/;
var regexUrl2 = /.+\.(fr|com|net)/;
if (regexUrl.test(formulaire.elements.url.value))
{
var donnees = {
titre: event.target.elements.titre.value,
url: event.target.elements.url.value,
auteur: event.target.elements.auteur.value
};
var nouveauLiens = creerLiensElts(donnees);
ajaxPost("https://oc-jswebsrv.herokuapp.com/api/lien", donnees, function (reponse){
// Création du message de confirmation d'ajout du nouveau lien
console.log("le Lien" + JSON.stringify(donnees) + " a été envoyé au serveur");
},
true
);
ajaxGet("https://oc-jswebsrv.herokuapp.com/api/liens", function(reponse){
var donneesRecues = JSON.parse(reponse);
console.log(donneesRecues[0].titre);
console.log(donneesRecues[0].url);
console.log(donneesRecues[0].auteur);
var nouveauLien = {
titre: donneesRecues[0].titre,
url: donneesRecues[0].url,
auteur: donneesRecues[0].auteur
};
var nouveauLienRecu = creerLiensElts(nouveauLien);
var lien = document.getElementsByClassName("lien");
document.getElementById("contenu").insertBefore(nouveauLienRecu, lien[0]);
});
var messageConfirme = document.createElement("p");
messageConfirme.textContent = 'Le lien ' + '"' + donnees.titre + '"' + ' a bien été ajouté !';
messageConfirme.style.color = "#428bca";
messageConfirme.style.backgroundColor = "#d7ecf6";
messageConfirme.style.padding = "25px";
messageConfirme.style.border = "1px solid #428bca";
messageConfirme.style.borderRadius = "5px";
document.getElementById("contConfirm").appendChild(messageConfirme);
formulaire.style.display = "none";
// Suppression du message de confirmation au bout de 2s
setTimeout(function () {
contConfirm.removeChild(messageConfirme);
document.querySelector("body").insertBefore(bouttonElt, document.querySelector("div"));
}, 2000);
event.preventDefault();
}
else if (regexUrl2.test(formulaire.elements.url.value))
{
var donnees = {
titre: event.target.elements.titre.value,
url: "http://" + event.target.elements.url.value,
auteur: event.target.elements.auteur.value
};
var nouveauLiens = creerLiensElts(donnees);
ajaxPost("https://oc-jswebsrv.herokuapp.com/api/lien", donnees, function (reponse){
// Création du message de confirmation d'ajout du nouveau lien
console.log("le Lien" + JSON.stringify(donnees) + " a été envoyé au serveur");
},
true
);
ajaxGet("https://oc-jswebsrv.herokuapp.com/api/liens", function(reponse){
var donneesRecues = JSON.parse(reponse);
console.log(donneesRecues[0].titre);
console.log(donneesRecues[0].url);
console.log(donneesRecues[0].auteur);
var nouveauLien = {
titre: donneesRecues[0].titre,
url: donneesRecues[0].url,
auteur: donneesRecues[0].auteur
};
var nouveauLienRecu = creerLiensElts(nouveauLien);
var lien = document.getElementsByClassName("lien");
document.getElementById("contenu").insertBefore(nouveauLienRecu, lien[0]);
});
var messageConfirme = document.createElement("p");
messageConfirme.textContent = 'Le lien ' + '"' + donnees.titre + '"' + ' a bien été ajouté !';
messageConfirme.style.color = "#428bca";
messageConfirme.style.backgroundColor = "#d7ecf6";
messageConfirme.style.padding = "25px";
messageConfirme.style.border = "1px solid #428bca";
messageConfirme.style.borderRadius = "5px";
document.getElementById("contConfirm").appendChild(messageConfirme);
formulaire.style.display = "none";
// Suppression du message de confirmation au bout de 2s
setTimeout(function () {
contConfirm.removeChild(messageConfirme);
document.querySelector("body").insertBefore(bouttonElt, document.querySelector("div"));
}, 2000);
event.preventDefault();
}
});
});
Non il ne faut pas utiliser sessionStorage, les activités sont toujours faisable avec ce qu'on apprend dans les cours.
Pour que le lien que tu as ajouté reste, je vais te mettre sur une piste, il faut que lorsque ton lien est ajouté sur le serveur, tu le récupères sur le serveur juste après pour ensuite l'afficher, et pour récupérer quelque chose sur le serveur, une fonction ajaxGet à été définie dans le cours. Je ne t'en dis pas plus, essaie déjà avec ça
Merci beaucoup Clément Patigny, j'ai réussi c'était assez simple finalement, mais je n'y avais absolument pas pensé.
Par contre j'ai toujours le premier problème et j'ai encore rencontré la même erreur (plusieurs fois), qui ne se produit plus lorsque le serveur est moins utilisé. il y a un problème entre le délai de traitement de la requête ajaxPost et celui de la requête ajaxGet, le deuxième étant manifestement plus rapide. J'ai peut-être une solution, je verrais cela lundi là aussi c'est tout bête mais il faut y penser.
- Edité par DominiqueQuaintenne1 13 avril 2018 à 17:54:57
je vois que le Post date de pas si longtemps, du coup je me permets de poser ma question ici.
Premièrement, quand je crée mon lien, il s'envoie bien sur le serveur.
Mais quand j'utilise ajaxGet(...) , je récupère un lien d'une autre personne, mais pas le mien , c'est normal ??
Je n'arrive pas non plus à conserver mon lien après rechargement de la page. Pourtant j'ai utilisé ajaxGet après ajaxPost, ce qui est logique.
Voici le bout du code correspondant à ajaxPost et ajaxGet :
// Ajout d'un gestionnaire d'évènement sur la validation du formulaire
// On applique la méthode 'addEventListener' sur le formulaire 'formAjoutLienElt'
formAjoutLienElt.addEventListener("submit", function(e) {
// On vérifie si l'url renseignée contient http:// ou https://
var urlSaisie = formAjoutLienElt.elements.url.value;
var urlValide = "";
var regex = /\b(http|https)\:\/\//;
if (!regex.test(urlSaisie)) {
urlValide = "http://" + urlSaisie;
} else {
urlValide = urlSaisie;
};
// Je récupère les valeurs des 3 <input> du formulaire
var lienElt = {
titre: formAjoutLienElt.elements.titre.value,
url: urlValide,
auteur: formAjoutLienElt.elements.auteur.value
};
ajaxPost("https://oc-jswebsrv.herokuapp.com/api/lien", lienElt,
function (reponse) {
console.log("Le lien " + JSON.stringify(lienElt) + "a bien été envoyé au serveur");
},
true // Valeur du paramètre isJson
);
ajaxGet("https://oc-jswebsrv.herokuapp.com/api/liens", function(liens){
var donneesRecues = JSON.parse(liens);
var lienRecu = {
titre: donneesRecues[0].titre,
url: donneesRecues[0].url,
auteur: donneesRecues[0].auteur
};
// Création du nouveau lien et positionnement au dessus de la liste
var nouveauLien = creerElementLien(lienRecu);
divContenuElt.insertBefore(nouveauLien, divContenuElt.firstChild);
});
// Disparition du formulaire et réapparation du bouton "ajouter un lien"
divAjouterLien.replaceChild(boutonAjouterLienElt, formAjoutLienElt);
je comprends le principe d'envoyer sur le serveur, et de récupérer, mais là je sais pas quoi faire
Je vais répondre à votre première question, n'oubliez pas que le serveur est partagé avec l'ensemble des apprenants, donc vous récupérez l'ensemble des éléments qui s'y trouvent ceux que vous avez créés et ceux des autres apprenants. Aussi à titre personnel j'avais retardé l'exécution de la requête ajaxGet pour que le traintement de la requête ajaxPost puisse être achevé avant, mais il y a un moyen beaucoup plus simple à l'aide de variable pour gérer le nouveau lien et le positionnement de la requête ajaxGet. Cette modification de positionnement vous permettra également de conserver votre lien lors du rechargement. Prenez le temps et vous trouverez.
merci pour la réponse. J'ai cherché mais je suis toujours bloqué :) c'est si simple que ça ?
Pour la variable, si je fais quelque chose dans ce style :
ajaxPost("https://oc-jswebsrv.herokuapp.com/api/lien", lienElt,
function (reponse) {
console.log("Le lien " + JSON.stringify(lienElt) + "a bien été envoyé au serveur");
},
true // Valeur du paramètre isJson
);
var banane = ajaxGet("https://oc-jswebsrv.herokuapp.com/api/liens", function(liens){
var donneesRecues = JSON.parse(liens);
var lienRecu = {
titre: donneesRecues[0].titre,
url: donneesRecues[0].url,
auteur: donneesRecues[0].auteur
};
});
// Création du nouveau lien et positionnement au dessus de la liste
var nouveauLien = creerElementLien(banane);
divContenuElt.insertBefore(nouveauLien, divContenuElt.firstChild);
C'est dans ce sens là , ou pas ? (voir variable banane), j'ai mis la création du lien à part cette fois
ou bien il faut insérer ajaxGet dans ajaxPost ; ou inversement ?
Déjà pour respecter les consignes tu dois créer ton lien dans ta requête ajaxPost(). Dans cette même requête du dois insérer la création du message d'ajout, le système qui permet de faire disparaître le formulaire au profit du bouton d'ajout ainsi que la disparition du message d'ajout.
De plus ta requête ajaxGet() n'a pas besoin d'être imbriquée dans ajaxPost(), elle est toujours mal placée. Pourquoi? (voir ligne suivante)
On doit récupérer la liste des liens et plus particulièrement celui que nous avons créé à partir des données renvoyées par le serveur. Tu sais que le javaScript est un langage qui s'exécute ligne par ligne (de la ligne 1 à la ligne x), or quand tu recharges une page si tu places ta requête ajaxGet() après ou dans ta requête ajaxPost() tu ne pourras jamais récupérer le lien que tu as créé précédemment mais tu changeras "éternellement" ton lien en en créant un nouveau! (sauf à utiliser deux requêtes ajaxGet, une pour l'affichage immédiat et l'autre lors du rechargement. Mais ce n'est pas la meilleure façon de faire fonctionner son script, nous n'avons besoin que d'une requête ajaxGet() mais placée au "bon endroit").
Une fois que tu sais cela, si tu places ta requête ajaxGet() au bon endroit, tu devras avant ta requête ajaxGet() initialiser le liens à travers une première variable (en initialisant ce qui caractérise un lien: titre, url et auteur) puis dans ta requête ajaxGet() à travers une seconde variable créé ledit lien (qui est un objet!!!) à partir des données reçues du serveur et en ayant placé en paramètre le référence à la variable qui initialise ce nouveau lien.
Je ne te donne pas la solution mais te donne des indices c'est la meilleure façon de progresser!
Ensuite, moi ce que je faisais c'est que je créais mon lien directement à partir de lienElt (données du formulaire), alors qu'il faut créer le lien à partir des données récupérées du serveur !
Donc je dois envoyer lienElt (données du formulaire) sur le serveur ; et utiliser lienRecu (récupéré du serveur) pour créer le lien qui sera affiché ?! Si j'ai bien compris l'idée
Mais après quelques tests; pour pouvoir utiliser "lienRecu" il faut imbriquer ajaxPost dans ajaxGet ; car si je place ajaxGet avant ajaxPost, je n'arrive pas à récupérer le lien reçu, à moins qu'il y 'a une technique que je ne vois pas.
le code :
formAjoutLienElt.addEventListener("submit", function(e) {
// On vérifie si l'url renseignée contient http:// ou https://
var urlSaisie = formAjoutLienElt.elements.url.value;
var urlValide = "";
var regex = /\b(http|https)\:\/\//;
if (!regex.test(urlSaisie)) {
urlValide = "http://" + urlSaisie;
} else {
urlValide = urlSaisie;
};
// Je récupère les valeurs des 3 <input> du formulaire
var lienElt = {
titre: formAjoutLienElt.elements.titre.value,
url: urlValide,
auteur: formAjoutLienElt.elements.auteur.value
};
/*var lienElt = {
// Initialise le lien
init: function (titre, url, auteur) {
this.titre = formAjoutLienElt.elements.titre.value;
this.url = urlValide;
this.auteur = formAjoutLienElt.elements.auteur.value;
}
};*/
ajaxGet("https://oc-jswebsrv.herokuapp.com/api/liens", function(liens){
var donneesRecues = JSON.parse(liens);
/*var lienRecu = Object.create(lienElt);*/
var lienRecu = {
titre: donneesRecues[0].titre,
url: donneesRecues[0].url,
auteur: donneesRecues[0].auteur
};
/* lienRecu.init(donneesRecues[0].titre, donneesRecues[0].url, donneesRecues[0].auteur);*/
ajaxPost("https://oc-jswebsrv.herokuapp.com/api/lien", lienElt,
function creationLien(){
// Création du nouveau lien et positionnement au dessus de la liste
var nouveauLien = creerElementLien(lienRecu);
divContenuElt.insertBefore(nouveauLien, divContenuElt.firstChild);
// Disparition du formulaire et réapparation du bouton "ajouter un lien"
divAjouterLien.replaceChild(boutonAjouterLienElt, formAjoutLienElt);
//Création du message de validation qui apparait pendant 2 secondes
var messageConfirmationElt = document.createElement("p");
messageConfirmationElt.textContent = 'Le lien "' + lienElt.titre + '" a bien été ajouté';
messageConfirmationElt.style.color = "#095873";
messageConfirmationElt.style.backgroundColor = "#C8E9F7";
messageConfirmationElt.style.fontSize = "20px";
messageConfirmationElt.style.padding = "22px";
messageConfirmationElt.style.borderRadius = "5px";
document.body.insertBefore(messageConfirmationElt, divAjouterLien);
setTimeout(function() {
document.body.removeChild(messageConfirmationElt);
}, 2000);
},
true // Valeur du paramètre isJson
);
});
e.preventDefault();
});
});
En commentaire, j'avais utilisé create.Object() et l'initialisation comme vous me l'avez proposé; mais je les ai laissé en commentaire.
Au final, mon code ne fonctionne pas plus que ça car je récupère un autre lien , et au rechargement de la page il ne reste pas.
//Récupération des derniers liens publiés
// On initialise un lien vide
var lienVide = {
titre: "",
url: "",
auteur: ""
};
// on fait sa requête ajaxGet()
ajaxGet("https://oc-jswebsrv.herokuapp.com/api/liens", function(reponse) {
var tableauDerniersLiens = JSON.parse(reponse);
for(var i = 0 ; i < tableauDerniersLiens.length ; i++)
{
var lien = Object.create(lienVide);
lien.titre = tableauDerniersLiens[i].titre;
lien.url = tableauDerniersLiens[i].url;
lien.auteur = tableauDerniersLiens[i].auteur;
contenuElt.appendChild(creerElementLien(lien));
}
});
/*
....
*/
// Création de l'objet contenant les données du nouveau lien
var lien = {
titre: titreElt.value,
url: url,
auteur: auteurElt.value
};
//Envoi du lien
ajaxPost("https://oc-jswebsrv.herokuapp.com/api/lient", lien, true, function() {
var lienElt = creerElementLien(lien);
// Ajoute le nouveau lien en haut de la liste
contenuElt.insertBefore(lienElt, contenuElt.firstChild);
// Remplace le formulaire d'ajout par le bouton d'ajout
p.replaceChild(ajouterLienElt, formAjoutElt);
// Création du message d'information
var infoElt = document.createElement("div");
infoElt.classList.add("info");
infoElt.textContent = "Le lien \"" + lien.titre + "\" a bien été ajouté.";
p.insertBefore(infoElt, ajouterLienElt);
// Suppresion du message après 2 secondes
setTimeout(function () {
p.removeChild(infoElt);
}, 2000);
});
Oui, vous envoyez au serveur entrant sous forme d'un lien et vous le récupèrez sous forme d'un "tableau" et il faut le remettre sous la forme de lien pour qu'il soit affiché. Moi j'ai fait un autre script mais je n'ai eu que 8 donc je ne vous l'ai pas mis, le miens ne créé pas le lien dans ajaxPost et des petits détails comme cela, mais il fonctionnait parfaitement. Mais n'hésitez pas à créer un message sur le forume avec l'ensemble de votre code, mon sujet étant résolu, ceux qui ont plus collé aux consignes que moi ne se rendront peut-être pas sur mon post.
× 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.
voilà...