0

ERROR FOUND: Finally I found the error, I make a brief explanation of it in the next paragraph, since the code below, although it solves the error, does not do it for the error itself, but for changing the approach of the code, Exactly what was said below, by putting the indexes of the array with its own name, vue, understand that those indexes are attributes of the array object and not indexes of the array. To correct it the way I wanted to do it initially, I should go through the properties of the array and not index them.

BEGINNING OF THE POST: I'm having trouble showing my array data in an HTML list. Every time I drop an image on a specific div element, an object is inserted into the array whose position becomes the name of the object and not numbered as is usually the case, if an image is dragged again and the object already exists in the array, the quantity attribute of the object in the array is increased. The problem is when I try to show the contents of that array in an HTML list using v-for, the behavior it has is as if the array were empty. I have already verified that the array is not empty and I do not know what else to do.

<template>
<div>
    <div id="wrapper-ingredients">
        <div id="base">
            <img src="../img/base.svg" usemap="#image-map" alt="base">
            <drop id="pizza-base" @drop="handleDrop">
                <map name="image-map" id="image-map">
                    <area target="_self" alt="pizza-base" title="pizza-base"
                          coords="133,387,93,308,79,217,119,119,168,69,231,32,308,17,381,14,448,36,489,64,526,99,555,142,576,195,586,251,575,314,546,359,488,412,416,446,317,454,205,436"
                          shape="poly">
                </map>
            </drop>
        </div>

        <div id="ingredients">
            <drag class="drag" :transfer-data="bellpepper">
                <img src="../img/bellpepper-512.png" id="bellpepper" alt="pimiento amarillo" width="512"
                     height="512">
            </drag>
            <drag class="drag" :transfer-data="cheese">
                <img src="../img/cheese-512.png" alt="queso" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="corn">
                <img src="../img/corn-512.png" alt="maiz" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="mushroom">
                <img src="../img/mushroom-512.png" alt="seta" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="olive">
                <img src="../img/olive-512.png" alt="oliva" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="onion">
                <img src="../img/onion-512.png" alt="cebolla" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="pepperoni">
                <img src="../img/pepperoni-512.png" alt="pepperoni" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="tomato">
                <img src="../img/tomato-512.png" alt="tomate" width="512" height="512">
            </drag>
        </div>
    </div>
    <div id="wrapper-ticket">
        <ul>
            <li v-for="ingRec in ingredientsReceipt" >{{ingRec}}</li>
        </ul>
    </div>
</div>
</template>

<script>

import {Ticket} from "../model/Ticket.js"
import {Bellpepper} from "../model/Bellpepper.js"
import {Cheese} from "../model/Cheese.js"
import {Corn} from "../model/Corn.js"
import {Mushroom} from "../model/Mushroom.js"
import {Olive} from "../model/Olive.js"
import {Onion} from "../model/Onion.js"
import {Pepperoni} from "../model/Pepperoni.js"
import {Tomato} from "../model/Tomato.js"
import {Drag, Drop} from 'vue-drag-drop'

export default {
    components: {Drag, Drop},
    data() {
        return {
            ingredientsReceipt: [],
            bellpepper: new Bellpepper(2),
            cheese: new Cheese(3),
            corn: new Corn(1),
            mushroom: new Mushroom(2),
            olive: new Olive(3),
            onion: new Onion(4),
            pepperoni: new Pepperoni(5),
            tomato: new Tomato(6),
            ticket: new Ticket()
        }
    },
    methods: {
        handleDrop(data) {
            let x = event.clientX
            let y = event.clientY
            let img = document.createElement("img")
            img.setAttribute('src', data.img)
            img.setAttribute('name', data.name)
            img.style.position = 'absolute'
            img.style.width = '3.5%'
            img.style.height = '7%'
            img.style.left = x - img.offsetWidth / 2 - 50 + 'px'
            img.style.top = y - img.offsetHeight / 2 - 25 + 'px'
            img.style.zIndex = '1'
            document.querySelector('#pizza-base').appendChild(img)
            if (this.ingredientsReceipt[data.name] !== data) {
                this.ingredientsReceipt[data.name] = data

            } else {
                this.ingredientsReceipt[data.name].quantity++

            }
            img.addEventListener("click", () => {
                if (this.ingredientsReceipt[data.name].quantity > 0) {
                    this.ingredientsReceipt[data.name].quantity--
                    img.remove()
                } else {
                    img.remove()
                    delete this.ingredientsReceipt[data.name]
                }
            })
        },
    },
}
</script>

I tried to show the array directly without using v-for, showing only an empty array on the screen. If someone knows where to find the error, it would be very helpful.

9
  • 1
    consider sharing a fiddle or a pen to verify the code and help easily Commented Feb 9, 2019 at 5:09
  • I am using webpack and other npm dependencies, I have never used this kind of platform personally, but I think that to use this type of dependencies I must have a premium account, possible? Commented Feb 9, 2019 at 5:24
  • @J.Doe You may need to initialize this ingredientsReceipt array before v-for starts rendering. Commented Feb 9, 2019 at 5:34
  • @jom I would say that this is not possible in the past, as a reactive array is modified at the moment so it is initialized before I get the feeling that it would not fix the problem Commented Feb 9, 2019 at 5:40
  • @J.Doe Yep, a verifiable pen or fiddle would be nice. And no, you don't need a premium to add external dependencies, try codesandbox.io or codepen. Commented Feb 9, 2019 at 5:45

2 Answers 2

1

You add elements to this.ingredientsReceipt[data.name] = data Vue can't detect changes to the array using this direct access, you can read about it here:

https://vuejs.org/2016/02/06/common-gotchas/#Why-isn%E2%80%99t-the-DOM-updating

They also offer a solution - try ingredientsReceipt.$set(data.name, data)

Sign up to request clarification or add additional context in comments.

Comments

0

ok, I finally managed to fix it, the problem was that it was renaming each of the positions of the array. To solve it I used some functional programming, I have left the positions of the array numbered and I have applied a .filter() to them and I have worked with that obtained value. Now it works, but I will investigate more to know why it does not work with the renamed array positions.

I leave the new code with the changes made, I will also comment on the code that I had to delete, and which I guess is where the problem lies, in case someone is able to find the error.

<template>
<div>
    <div id="wrapper-ingredients">
        <div id="base">
            <img src="../img/base.svg" usemap="#image-map" alt="base">
            <drop id="pizza-base" @drop="handleDrop">
                <map name="image-map" id="image-map">
                    <area target="_self" alt="pizza-base" title="pizza-base"
                          coords="133,387,93,308,79,217,119,119,168,69,231,32,308,17,381,14,448,36,489,64,526,99,555,142,576,195,586,251,575,314,546,359,488,412,416,446,317,454,205,436"
                          shape="poly">
                </map>
            </drop>
        </div>

        <div id="ingredients">
            <drag class="drag" :transfer-data="bellpepper">
                <img src="../img/bellpepper-512.png" id="bellpepper" alt="pimiento amarillo" width="512"
                     height="512">
            </drag>
            <drag class="drag" :transfer-data="cheese">
                <img src="../img/cheese-512.png" alt="queso" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="corn">
                <img src="../img/corn-512.png" alt="maiz" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="mushroom">
                <img src="../img/mushroom-512.png" alt="seta" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="olive">
                <img src="../img/olive-512.png" alt="oliva" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="onion">
                <img src="../img/onion-512.png" alt="cebolla" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="pepperoni">
                <img src="../img/pepperoni-512.png" alt="pepperoni" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="tomato">
                <img src="../img/tomato-512.png" alt="tomate" width="512" height="512">
            </drag>
        </div>
    </div>
    <div id="wrapper-ticket">
        <ul>
            <li v-for="ingRec in ingredientsReceipt">{{ingRec.name + " X " + ingRec.quantity}}</li>
        </ul>
    </div>
</div>
</template>
<script>
import {Ticket} from "../model/Ticket.js"
import {Bellpepper} from "../model/Bellpepper.js"
import {Cheese} from "../model/Cheese.js"
import {Corn} from "../model/Corn.js"
import {Mushroom} from "../model/Mushroom.js"
import {Olive} from "../model/Olive.js"
import {Onion} from "../model/Onion.js"
import {Pepperoni} from "../model/Pepperoni.js"
import {Tomato} from "../model/Tomato.js"
import {Drag, Drop} from 'vue-drag-drop'

export default {
    components: {Drag, Drop},
    data() {
        return {
            ingredientsReceipt: [],
            bellpepper: new Bellpepper(2),
            cheese: new Cheese(3),
            corn: new Corn(1),
            mushroom: new Mushroom(2),
            olive: new Olive(3),
            onion: new Onion(4),
            pepperoni: new Pepperoni(5),
            tomato: new Tomato(6),
            ticket: new Ticket()
        }
    },
    methods: {
        handleDrop(data) {
            let x = event.clientX
            let y = event.clientY
            let img = document.createElement("img")
            img.setAttribute('src', data.img)
            img.setAttribute('name', data.name)
            img.style.position = 'absolute'
            img.style.width = '3.5%'
            img.style.height = '7%'
            img.style.left = x - img.offsetWidth / 2 - 50 + 'px'
            img.style.top = y - img.offsetHeight / 2 - 25 + 'px'
            img.style.zIndex = '1'
            document.querySelector('#pizza-base').appendChild(img)
            if (this.ingredientsReceipt.indexOf(data) === -1) {
                this.ingredientsReceipt.push(data)
            } else {
                let x = this.ingredientsReceipt.filter(arrayItem =>
                    arrayItem.name === data.name
                )
                x[0].quantity++
                console.log(x,this.ingredientsReceipt)
            }

            //HERE IS WHERE THE PROBLEM WILL BE...

            /*
            this.ingredientsReceipt[data.name] = (this.ingredientsReceipt[data.name] || 0) + 1
            if (this.ingredientsReceipt[data.name] !== data) {
                this.ingredientsReceipt[data.name] = data

            } else {
                this.ingredientsReceipt[data.name].quantity++

            }
            */
            img.addEventListener("click", () => {
                let x = this.ingredientsReceipt.filter( arrayItem => arrayItem.name === data.name)
                if (x[0].quantity > 0) {
                    x[0].quantity--
                    img.remove()
                } else {
                    img.remove()
                    delete this.ingredientsReceipt[data.name]
                }
            })
            /*console.log(this.ingredientsReceipt)*/
        },
    },
}
</script>

Thank You All for your help!!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.