Partage
  • Partager sur Facebook
  • Partager sur Twitter

Incrémenter la quantité d'un produit

dans les pages produit et panier

Sujet résolu
    24 novembre 2021 à 18:17:03

    Bonjour, j'ai une difficulté dans le cadre de mon projet. Dans la page produit, j'essaie de faire en sorte que lorsque l'utilisateur clique sur le bouton pour rajouter un produit au panier, mon code ajoute le produit au panier si le produit est un nouveau produit sélectionné mais qu'il augmente simplement la quantité dans le cas où le produit serait déjà présent dans le panier. Pour une raison que j'ignore, le code que j'ai écrit pour y parvenir ne fonctionne pas :

    class Product {
        constructor(id, number, coloration, image, alternative, name, price) {
            this.id = id;
            this.number = number;
            this.coloration = coloration;
            this.image = image;
            this.alternative = alternative;
            this.name = name;
            this.price = price;
        }
    }
    
    //créer un nouveau produit
    async function CreateProductForCart() {
        const request = await fetch("http://localhost:3000/api/products/" + product_ID);
        const result = await request.json();
        const valueForimage = await result.imageUrl;
        const valueForalternative = await result.altTxt;
        const valueForname = await result.name;
        const valueForprice = await result.price;
        const valueForID = await result._id;
    
        if (document.getElementById("quantity").value <= 0 || document.getElementById("quantity").value > 100 || isNaN(document.getElementById("quantity").value)) {
            alert("La quantité choisie pour votre produit n'est pas possible. Veuillez choisir une quantité différente.");
            return false;
        } else {
        let quantite = document.getElementById("quantity").value;
        let couleur = document.getElementById("colors").value;
    
        let OneProduct = new Product(valueForID, quantite, couleur, valueForimage, valueForalternative, valueForname, valueForprice);   
            
        return OneProduct;
        }    
    }
    
    //Ici, cette fonction vérifie l'existence d'un panier dans le localStorage,
    //puis dans le cas où il n'existe pas, vérifie qu'un produit avec le même ID
    //et couleur existe, et augmente la quantité si c'est le cas
    async function UpdateCart() {
        if (CreateProductForCart()) {   
            
            let OneProduct = await CreateProductForCart();
    
            if (!JSON.parse(localStorage.getItem('Allproducts'))) {
                let Cart = [];
                Cart.push(OneProduct);
                console.log("Le panier est vide, un produit y est ajouté.");
                return Cart;
            } else {
                let Cart = JSON.parse(localStorage.getItem("Allproducts"));
                for (let CartParts of Cart) {
                    if (OneProduct.id === CartParts.id && OneProduct.coloration === CartParts.coloration) {
                        OneProduct.number += CartParts.number;
                        console.log("On augmente la quantité pour un produit déjà présent dans le panier.");
                        return Cart;
                    } else { 
                        Cart.push(OneProduct);
                        console.log("Un nouveau produit est ajouté au panier.");  
                        return Cart;
                    }
                }
            }
        } else {
            return false;
        }
    }
        
    //vider le local puis remettre le tableau mis à jour
    async function UpdateStorage() {
    
        if (UpdateCart()) {
            let Cart = await UpdateCart();
    
            localStorage.removeItem('Allproducts');
            localStorage.setItem('Allproducts', JSON.stringify(Cart));
            console.log("Le Storage s'est mis à jour.");
        } else {
            return false;
        }
        
    }

    Je veux aussi que sur la page du panier, l'utilisateur puisse encore modifier la quantité du produit si besoin. Cette nouvelle quantité doit être enregistrée dans le localStorage et être conservée en cas de rechargement de la page par exemple :

    let Cart = [];
    
    function getAllProducts() {
        Cart = localStorage.getItem("Allproducts");
        console.log("Les produits sont récupérés.");
    }
    
    getAllProducts();
    
    for (let CartParts of Cart) {
        //les éléments du panier apparaissent dans le DOM de panier.html
        
        console.log("Un nouveau produit est rajouté dans le panier.");
    }
    
    //la fonction récupère la valeur de l'input qui vient d'être modifiée par
    //l'utilisateur et la change avec le produit correspondant présent dans le
    //panier
    function UpdateQtyForCartParts(ProductChanged) {
        let Input = document.querySelector(".cart__item__content__settings__quantity input");
    
        ProductChanged.number = Input.value;
    
        let Element_modified = Cart.indexOf(ProductChanged);
        Cart.splice(Element_modified, 1, ProductChanged);
    }
    
    function UpdateStorage() {
        localStorage.removeItem('Allproducts');
        localStorage.setItem('Allproducts', JSON.stringify(Cart));
        console.log("Le Storage s'est mis à jour.");
    }
    
    for (let CartParts of Cart) {
        let Input = document.querySelector(".cart__item__content__settings__quantity input");   
        Input.addEventListener('input', function (CartParts) {
            CartParts.preventDefault();
            UpdateQtyForCartParts(CartParts);
            UpdateStorage();
        }
        )
    }

    Merci de toute aide !



    • Partager sur Facebook
    • Partager sur Twitter
      24 novembre 2021 à 20:34:05

      Salut,

      Ta fonction 'UpdateStorage' (L.71) ne va pas : ta condition test le retour d'une exécution de la fonction asynchrone 'UpdateCart' (donc tu l'exécute déjà 1 fois), or toute les fonctions asynchrone renvoie des promesses, donc ta condition est toujours vraie... Ensuite, sur la ligne juste en dessous, tu relances une deuxième fois cette même fonction asynchrone 'UpdateCart' et cette fois tu en attend le résultat pour le stocker dans une variable.

      Bref, je vois déjà un double appel qui ne devrait pas être là.

      En vérité, je vois a nouveau le même problème de conditions et de double invocation sur promesse à la ligne 40 et à la ligne 42. Vraiment cette condition sert a rien : elle sera tout le temps vrai puisque tu testes la promesse elle-même et pas son résultat.

      Hors mis ces erreurs et sans vouloir t'offenser, ton code est vraiment super redondant et pas clair. À croire que tu préfères te compliquer la vie... Un exemple :

      Ligne 44 : Pourquoi tu ne stock pas le résultat de ton getItem sur ton localstorage dans une variable, PUIS tu t'est si la valeur est null (parce que si c'est le cas tu va te retrouver avec une erreur lors de ton JSON.parse et ça va arrêter cette partie de ton code), PUIS tu stock le résultat de JSON.parse (si ça n'était pas null, ou tu crées un nouvel array) dans une variable. En 2 lignes ça donne :

      const allProducts = localStorage.getItem('Allproducts');

      const cart =  allProducts ? JSON.parse(allProducts) : [];

      Après ta plus qu'à vérifier la propriété length de 'cart' pour ta condition (qui marchera sans risque d'erreur cette fois). Et comme ça tu évites de demandé deux fois ton allProducts au localstorage, tu évites de le parse 2 fois le résultat, tu arrêtes aussi de déclarer ta variable 'cart' deux fois dans deux scopes differentes (ta de la chance ça ne fait pas de problème pour ce cas ci, mais quand même...) d'autant que ça devrait être une déclaration 'const' et pas 'let' en toute logique...

      Bref, je veux juste te suggérer de te poser 10min et de revoir la logique de ton code, de ne surtout pas hésiter à caler des console.log partout pour bien que tu comprenne ce qui ce passe, et je suis sûr que tu seras confronté à beaucoup moins de problème...

      Aussi par pitié (!!) vas jeter un œil à la documentation sur les scopes et les différentes déclarations ('const', 'let', 'var'...) je vois souvent tes posts passer et je relève toujours les mêmes erreurs et incohérences de scope et de déclaration. Entend moi : 90 à 95% de tes déclarations devrait être pour des 'const' pas des 'let' ! Un 'let' ça ne s'utilise en bonne programmation QUE lorsque la valeur est amené à changer !

      PS: déso pas de balise de code sur mon téléphone...

      -
      Edité par BrainError 24 novembre 2021 à 20:38:29

      • Partager sur Facebook
      • Partager sur Twitter
        25 novembre 2021 à 19:08:38

        Je te remercie de ta réponse, j'ai essayé de modifier mon code selon tes observations mais il semble y avoir un autre problème. Avec mon code suivant :

        async function UpdateCart() {
            
            const OneProduct = await CreateProductForCart();
            const AllProducts = localStorage.getItem('Allproducts');
            const Cart =  AllProducts ? JSON.parse(AllProducts) : [];
        
            if (Cart.length = 0) {
        
                Cart.push(OneProduct);
                console.log("Le panier est vide, un produit y est ajouté.");
                return Cart; 
        
            } else {
               for (let CartParts of Cart) {    
                    if (OneProduct.id === CartParts.id && OneProduct.coloration === CartParts.coloration) {
                        OneProduct.number += CartParts.number;
                        console.log("On augmente la quantité pour un produit déjà présent dans le panier.");
                        return Cart;
                    } else { 
                        Cart.push(OneProduct);
                        console.log("Un nouveau produit est ajouté au panier.");  
                        return Cart;
                    }
                } 
            }
        }

        Lors de mes tests, ma console me renvoie ceci :

        La ligne 96 indiquée par la console étant celle-ci :

        const cart =  allProducts ? JSON.parse(allProducts) : [];

        De ce que j'en comprends, cette réponse de la console arrive pour me dire qu'il ne peut parser un élément "undefined", du fait que l'élément aurait déjà été parsé. Mais ce n'est pas justement ce que cette ligne de code était sencée éviter ?

        Par ailleurs, tu as dit que mon code n'était pas clair à cause du mauvais usage des varaibles et des doubles appels. Puis-je te demander s'il y avait d'autres raisons dûes à ce manque de clarté en dehors de ces deux choses ?

        • Partager sur Facebook
        • Partager sur Twitter
          26 novembre 2021 à 8:43:12

          Salut,

          non ça signifie surtout que tu as bien quelque chose d'enregistrer dans ton localStorage sous cette clé, et que c'est pas du JSON. Il y a moyen que ça soit une string valant 'undefined' textuellement en fait (donc pas du JSON).

          Si ton entré était bien vide, getItem te renverrais null et pas undefined... Exemple sur une page google.fr :

          Sinon, ton code est quand même plus claire maintenant en effet.

          -
          Edité par BrainError 26 novembre 2021 à 8:43:56

          • Partager sur Facebook
          • Partager sur Twitter
            30 novembre 2021 à 9:47:35

            Je pense avoir trouvé, merci beaucoup.
            • Partager sur Facebook
            • Partager sur Twitter

            Incrémenter la quantité d'un produit

            × 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