lucaspulliese / vue-cool-lightbox

Vue.js lightbox inspired by fancybox.
https://vue-cool-lightbox.lucaspulliese.com
341 stars 54 forks source link

TypeError: Cannot read property 'match' of undefined #65

Closed Yann-Chapuis closed 3 years ago

Yann-Chapuis commented 3 years ago

Hi,

I have an image gallery that worked fine with data (not dynamic). I implemented axios to query the API and retrieve the images. Everything works, except when I click on an image, i have this error :

chrome_2020-12-08_12-11-11

My full file:

<template>
    <div id="photos" class="container-fluid">
        <div class="container">
            <div class="row">
                <div class="col text-center">
                    <h2>Photos</h2>
                    <div class="divider-c"> <span></span></div>
                </div>
            </div>
        </div>

        <CoolLightBox 
        :items="projects" 
        :index="index"
        @close="index = null">
        </CoolLightBox>

        <div class="title-container">
            <div class="filters">
                <span class="filter" v-bind:class="{ active: currentFilter === 'TOUTES' }" v-on:click="setFilter('TOUTES')">Toutes</span>
                <span class="filter" v-bind:class="{ active: currentFilter === 'MUSICIENS' }" v-on:click="setFilter('MUSICIENS')">Musiciens</span>
                <span class="filter" v-bind:class="{ active: currentFilter === 'SCENE' }" v-on:click="setFilter('SCENE')">Scène</span>
            </div>
        </div>

        <transition-group class="row images-wrapper projects" name="projects" style="margin:0;">

                <!-- eslint-disable -->
                    <div
                        class="col-lg-3 col-md-4 col-sm-12 image_list"
                        v-for="(project, imageIndex) in projects"
                        v-if="currentFilter === project.categorie || currentFilter === 'TOUTES'" 
                        :key="imageIndex"
                        @click="index = imageIndex"
                        :style="{ backgroundImage: 'url('+url_admin+'/images/_gallery/'+project.url_image + ')', cursor: 'zoom-in' }"
                    ></div>
                <!-- eslint-enable -->

        </transition-group> 

    </div>
</template>
<script>
import CoolLightBox from 'vue-cool-lightbox';
import 'vue-cool-lightbox/dist/vue-cool-lightbox.min.css'
import axios from 'axios';

export default {
    name: 'Photos',
    components: {
        CoolLightBox,
    },
    data: function () {
        return {
            currentFilter: 'TOUTES',
            projects: [],
            url_admin: process.env.VUE_APP_ADMIN_URL,
            index: null
        }
    },
    mounted () {
        axios
        .get(process.env.VUE_APP_API_URL+'/getPhotos')
        .then(response => (this.projects = response.data.data))
    },
    methods: {
        setFilter: function(filter) {
            this.currentFilter = filter;
        }
    }
}
</script>

When i used this code without axios, that worked :

<CoolLightBox 
        :items="projects" 
        :index="index"
    @close="index = null">
</CoolLightBox>
<div
    class="col-lg-3 col-md-4 col-sm-12 image_list"
    v-for="(project, imageIndex) in projects"
    v-if="currentFilter === project.category || currentFilter === 'TOUTES'" 
    :key="imageIndex"
    @click="index = imageIndex"
    :style="{ backgroundImage: 'url(' + project.src + ')' }"
></div>
import CoolLightBox from 'vue-cool-lightbox';
import 'vue-cool-lightbox/dist/vue-cool-lightbox.min.css'

export default {
    name: 'Photos',
    components: {
        CoolLightBox,
    },
    data: function () {
        return {
            currentFilter: 'TOUTES',
            projects: [
                {id: "1", src: "http://www.blablou.com/images/musiciens/1.jpg", category: 'MUSICIENS'},
                {id: "2", src: "http://www.blablou.com/images/musiciens/2.jpg", category: 'SCENE'},
                {id: "3", src: "http://www.blablou.com/images/musiciens/3.jpg", category: 'MUSICIENS'},
                {id: "4", src: "http://www.blablou.com/images/musiciens/4.jpg", category: 'SCENE'},
            ],
            index: null
        }
    },
    methods: {
        setFilter: function(filter) {
            this.currentFilter = filter;
        }
    }
}

Someone can help me ?

lucaspulliese commented 3 years ago

Hello @Yann-Chapuis! I'm going to take a look at this and I will tell you if I find any solution.

lucaspulliese commented 3 years ago

Hello again @Yann-Chapuis!

Look at this JSFiddle, I did like a fake fetch using a setTimeout function, looks like it's working fine.

Can you do a console.log of the response from the axios call? I think maybe it's something from the format of the data that you are getting.

Yann-Chapuis commented 3 years ago

Thank you for your answer @lucaspulliese =)

About my console.log : chrome_2020-12-11_07-52-16

I tried to use a setTimeout and a function to defined my index (@click), but still not working.

I simplified my code and put the real url on this JSFiddle. It's exactly what i have on my project, and my "v-for" loop displays images well. The problem is when clicking on the image to display "CoolLightBox". I did a "console.log(index)" in my setIndex (@click) function, and it returns the index 0, 1, 2, 3 ... which matches well.

I really don't understand where the problem is coming from.

Yann-Chapuis commented 3 years ago

I solved the problem. @lucaspulliese you were right, the problem came from the answer from my API, i had something like that before :

[RESPONSE FROM API]
data: [
{
categorie: "MUSICIENS",
ranking: 1,
url_image: "1.jpg"
},
{
categorie: "SCENE",
ranking: 1,
url_image: "s1.jpg"
},

And on my view, i used this line to display each pic : :style="{ backgroundImage: 'url('+url_admin+'/images/_gallery/'+project.url_image + ')', cursor: 'zoom-in' }"

I changed the name of my column "url_image" to "src", and i return the full url from my API, not just the picture's name "1.jpg" but "https://www.myapi/images/_gallery/1.jpg". I changed it from my API, but i guess we can change it on our view.

Now with that, that work :

[RESPONSE FROM API]
data: [
{
categorie: "MUSICIENS",
ranking: 1,
src: "https://www.myapi.fr/images/_gallery/1.jpg",
},
{
categorie: "SCENE",
ranking: 1,
src: "https://www.myapi.fr/images/_gallery/1.jpg",
},

:style="{ backgroundImage: 'url('+project.src+')', cursor: 'zoom-in' }"

Thx for your help @lucaspulliese , and thank you for this great component =)

lucaspulliese commented 3 years ago

You are welcome @Yann-Chapuis! And thanks! I'm glad that you liked it.

And I have to say I'm sorry that I couldn't help you when you sent me the JSFiddle, I had a really busy week.

For you to consider, you can change the key of the object to be used as url image or video url, you only need to use the prop srcName, by defaul is "src".

Cheers!