2

what i want to achieve:
load an image from jwt token protected source
the server return the image as base64 string and i'll load this string as background url on the image

parent component:

<template lang="html">
     <myImage v-for="photo in form.photos" :photo="photo" @delphoto="deleteImage"></myImage>
</template>

export default {
        components: {
            myImage,
        },
        data(){
            return {
                form: {
                    photos: [
                {
            id: 1,
            thumbnail: "logo1.png"
            },
                {
            id: 2,
            thumbnail: "logo2.png"
            },
                {
            id: 3,
            thumbnail: "logo3.png"
            },
                {
            id: 4,
            thumbnail: "logo4.png"
            },
            ]

                },

            }
        },
        methods: {
            deleteImage(myphoto)
            {
                this.form.photos.splice(this.form.photos.indexOf(myphoto), 1);
            }
        }
    }

myImage component

<template>
        <div v-if="loaded" class="img">
            <img class="albumimg" :style="{ background: img}" :title="title">
            <p @click="delimage">delete</p>
        </div>
        <div v-else class="img">
            <img class="loading" style="background: url('/images/spinner.gif')">
        </div>
</template>
<script>
    export default {
        data(){
            return {
                img: null,
                loaded: false
            }
        },
        props: {
            photo: {
                required: true
            },
            title: {
                default: ''
            },
        },
        created() {
            this.imgurl()
        },
        methods: {
            delimage() {
              this.$emit('delphoto', this.photo)
            },
            imgurl() {
                this.$http.get("/api/images/" + this.photo.id).then(response => {
                    this.img = "url('" + response.data + "')"
                    this.loaded = true
                }, response => {
                });
            },
        }
    }
</script>

now if i delete a photo (splice) from the form.photos array always the last image get removed. when i remove the green image

the blue image disappears

when i check the form.photos array, the correct image was removed, only the img data attribute from myImage component is still the old value from the previous array position 1.

i was able to bypass this issue by adding a watch on the photo prop and refetch the base64 string which cause a new get request for every image

watch: {
   photo: function (val) {
      this.imgurl()
   }
},

is there any way to remove an array item (child component) and display the correct result without fetching all images again within the child component?

thanks

1 Answer 1

5

Try this.

<myImage v-for="photo in form.photos" :key="photo.id" :photo="photo" @delphoto="deleteImage"></myImage>

From the current documentation.

In 2.2.0+, when using v-for with a component, a key is now required.

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

4 Comments

thx for your answer, same result. the array item was correctly removed but the img variable within my myImage component is the value from the old array item on this position
if i add the base64 string direclty to the photos array and dont fetech the string at component created all is working fine. so this has something todo with the axios get request
@markus My apologies. The key property should be "photo.id". I updated the answer. The bug is obvious in retrospect; you cannot use the index because the array changes; the indexes will all change. /facepalm moment.
thanks a lot, now all works fine! i tried to fix it for 4 days now... thank you very much!!!

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.