unable to do a .find() loop in vue js component on created

I’m currently building a simple app with Vue js (and learnign it by the same occasion).

Here is the app : https://osr-app-2a8b6.web.app/

So when you are on the homepage that displays the list of events and then click on details, you end up on the single page of the event, that works perfectly, but when you load that single page without navigating to it (just reload the page), nothing is showing and I’ve got an

Uncaught (in promise) TypeError: Cannot read property 'content' of undefined

which I don’t have when navigating.

So here is the my router code :

const router = createRouter({
    history: createWebHistory(),
    routes: [
        {name: 'home', path: '/', component: Home},
        {name: 'fav', path: '/favoris', component: FavoriteEvents},
        {name: 'single-event', path: '/:eventId', component: SingleEvent}
    ]
});

and my component :

<script>
    import SingleCta from './SingleCta.vue';
    import SingleHeader from './SingleHeader.vue';
    import PartnerList from './PartnerList.vue';
    import GalleryCarousel from './GalleryCarousel.vue';
    import TheProgram from './TheProgram.vue';
    import DropdownList from './DropdownList.vue';
    
    export default {
        components: {
            SingleCta,
            SingleHeader,
            PartnerList,
            GalleryCarousel,
            TheProgram,
            DropdownList,
        },
        data() {
            return {
                singleEvent: '',
                title: '',
                serieType: '',
                day: '',
                time: '',
                date: '',
                where: '',
                dropDowns: [],
                gallery: [],
                partners: [],
                people: [],
                program: '',
                description: '',
                adProgram: {},
                txtColor: '',
                bgColor: ''
            }
        },
        computed: {
            singleEventClass(){
                return 'page single-event ' + 'single-event--txt-' + this.txtColor + ' ' + 'single-event--bg-' + this.bgColor
            }
        },
        created() {
            const eventId = this.$route.params.eventId;
            const selectedEvent = this.$store.state.events.find(event => event.id === eventId);

            console.log(eventId) // return rhapsody-in-blue
            console.log(this.$store.state.events) // return my array with 3 events
            console.log(selectedEvent) // return undefined WHY???

            const selectedEventContent = selectedEvent.content;
            
            console.log(selectedEventContent) // return undefined WHY???

            this.singleEvent = selectedEvent;
            this.title = selectedEvent.title;
            this.serieType = selectedEvent.serieType;
            this.day = selectedEvent.day;
            this.date = selectedEvent.date;
            this.time = selectedEvent.time,
            this.where = selectedEvent.where,
            this.bgColor = selectedEvent.bgColor,
            this.txtColor = selectedEvent.txtColor,
            this.dropDowns = selectedEventContent.dropDowns;
            this.gallery = selectedEventContent.gallery
            this.partners = selectedEventContent.partners
            this.people = selectedEventContent.people
            this.program = selectedEventContent.program
            this.description = selectedEventContent.description
            this.adProgram = selectedEventContent.adProgram
        }
    }
</script>

the problem seems to be here:

const selectedEventContent = selectedEvent.content;

it returns me undefined :

TypeError: Cannot read property 'content' of undefined

but you can see that just before I’m logging the eventId and that returns the correct event ID:

rhapsody-in-blue

and also I’m logging the this.$store.state.events

which returns my events array :

Proxy {}
[[Handler]]: Object
[[Target]]: Array(3)
0: {bgColor: "pink", content: {…}, date: "30.09.20", day: "mercredi", id: "rhapsody-in-blue", …}
1: {bgColor: "pink", content: {…}, date: "23.09.21", day: "jeudi", id: "hommage-a-armin-jordan", …}
2: {bgColor: "black", content: {…}, date: "18.09.21", day: "samedi", id: "septembre-musical-montreux", …}
length: 3
[[Prototype]]: Array(0)
[[IsRevoked]]: false

So why is the .find() loop on that array return me undefined?

Again that works when navigating but not on load.

You’re trying to access data that doesn’t exist in your store yet. This is why it works fine when you navigate to the route, but not when you refresh the page on the same route.

const selectedEvent = this.$store.state.events.find(event => event.id === eventId);

i.e. This returns undefined because at the time you invoke this the event data doesn’t exist.

The reason why this line: console.log(this.$store.state.events) appears to log your data just fine is because by the time you go into your console and reveal the contents of the array the data has been resolved. If you were to run that log on the same line, but replace it with console.log(this.$store.state.events[0]), you should get an undefined.

The simplest solution is to change selectedEvent to be a computed property and use a v-if within your template to avoid rendering the part of the template that relies on this data until you actually have the data.

Hi James,

Thank you for you answer, unfortunately it doesn’t change anything, I’ve been trying different way to get the data + your solution, but it is still undefined, well I guess I’m missing something. Would you mind have a look at the full code for that component and pointing me where and what to change so it works?

Do I need to remove the creted(){} part? So then how do I set my different variables (data)? I’, getting confused.

So this is my component :

<template>
    <div :class="singleEventClass">
        <div class="page__content">
            <SingleCta :id="$route.params.eventId"/>
            <SingleHeader 
                :serie-type="serieType"
                :title="title"
                :day="day"
                :time="time"
                :date="date"
                :where="where"
                :people="people"
            />
            <PartnerList :partners="partners"/>
            <GalleryCarousel :images="gallery" />
            <TheProgram 
                :people-list="people"
                :program="program"
                :description="description"
                :ad="adProgram"
            />  
            <DropdownList :dropdowns="dropDowns" />
        </div>
    </div>
</template>
<script>
    import SingleCta from './SingleCta.vue';
    import SingleHeader from './SingleHeader.vue';
    import PartnerList from './PartnerList.vue';
    import GalleryCarousel from './GalleryCarousel.vue';
    import TheProgram from './TheProgram.vue';
    import DropdownList from './DropdownList.vue';
    
    export default {
        components: {
            SingleCta,
            SingleHeader,
            PartnerList,
            GalleryCarousel,
            TheProgram,
            DropdownList,
        },
        data() {
            return {
                singleEvent: '',
                title: '',
                serieType: '',
                day: '',
                time: '',
                date: '',
                where: '',
                dropDowns: [],
                gallery: [],
                partners: [],
                people: [],
                program: '',
                description: '',
                adProgram: {},
                txtColor: '',
                bgColor: ''
            }
        },
        computed: {
            singleEventClass(){
                return 'page single-event ' + 'single-event--txt-' + this.txtColor + ' ' + 'single-event--bg-' + this.bgColor
            },
            selectedEvent(){
                return this.$store.state.events.find(event => event.id === this.$route.params.eventId)
            }
        },
        created() {
            const eventId = this.$route.params.eventId;
            const selectedEvent = this.$store.state.events.find(event => event.id === eventId);

            console.log(eventId) // return rhapsody-in-blue
            console.log(this.$store.state.events) // return my array with 3 events
            console.log(selectedEvent) // return undefined WHY???

            const selectedEventContent = selectedEvent.content;
            
            console.log(selectedEventContent) // return undefined WHY???

            this.singleEvent = selectedEvent;
            this.title = selectedEvent.title;
            this.serieType = selectedEvent.serieType;
            this.day = selectedEvent.day;
            this.date = selectedEvent.date;
            this.time = selectedEvent.time,
            this.where = selectedEvent.where,
            this.bgColor = selectedEvent.bgColor,
            this.txtColor = selectedEvent.txtColor,
            this.dropDowns = selectedEventContent.dropDowns;
            this.gallery = selectedEventContent.gallery
            this.partners = selectedEventContent.partners
            this.people = selectedEventContent.people
            this.program = selectedEventContent.program
            this.description = selectedEventContent.description
            this.adProgram = selectedEventContent.adProgram
            
        }
    }
</script>

And here is my main.js part where I get the data from an JSON file, maybe it’s also at this point that I’m not getting the data the right way!

import 'normalize.css'
import { createApp } from 'vue'
import { createStore } from 'vuex'
import { createRouter, createWebHistory } from 'vue-router'
import axios from 'axios'
import App from './App.vue'
import Home from './components/Home.vue'
import SingleEvent from './components/SingleEvent.vue'
import FavoriteEvents from './components/FavoriteEvents.vue'
import './registerServiceWorker'
import gsap from 'gsap';
//import {Power4} from 'gsap';

const router = createRouter({
    history: createWebHistory(),
    routes: [
        {name: 'home', path: '/', component: Home},
        {name: 'fav', path: '/favoris', component: FavoriteEvents},
        {name: 'single-event', path: '/:eventId', component: SingleEvent}
    ]
});

const store = createStore({
    state(){
        return {
            dataUrl: 'https://osr-app-2a8b6-default-rtdb.europe-west1.firebasedatabase.app/events.json',
            // dataUrl: 'https://osr-osr20ma32.ideative.io/fr/?json',
            connectionStatus: '',
            currentPage: 'Concerts',
            currentFilter: 'all',
            events: [],
            filteredEvents: [],
            // serieType: [],
            favorites: [],
            isLoading: true
        };
    },
    // getters: {
    //     isOnline: function () {
    //         if(navigator.onLine){
    //           return true;
    //         } else {
    //           return false;
    //         }
    //     }
    // },
    mutations: {
        toggleToFavorites(state, payload){
            //console.log('togglew to fav from MAIN js');
            if(state.favorites.includes(payload.concert)){
                const index = state.favorites.indexOf(payload.concert);
                state.favorites.splice(index, 1);
            } else {
                state.favorites.push(payload.concert);
            }
            localStorage.setItem('favEvents', JSON.stringify(state.favorites));
            console.log(localStorage.getItem('favEvents'));
        },
        checkConnectionStatus(state) {	
            if (navigator.onLine){
                state.connectionStatus = 'online';
            } else{
                state.connectionStatus = 'offline';
            }
        },
        getAndSetData(state){
            if(state.connectionStatus === 'online'){ // if internet connection, fetch data from porvided API URL
                axios.get(state.dataUrl)
                .then(response => {
                  // handle success
                  state.events.length = 0;
                  state.events.push(... response.data);
      
                  state.filteredEvents.lenght = 0;
                  state.filteredEvents.push(... state.events);
                  
                  localStorage.setItem('osrEvents', JSON.stringify(response.data));
                })
                .catch(function (error) {
                  // handle error
                  console.log(error);
                })
                .then(function () {
                  // always executed
                });
            } else { // Otherwise check if there is a cached version of that data in the localStorage
              const localData = JSON.parse(localStorage.getItem('osrEvents'));
              state.events.length = 0;
              state.events.push(... localData);
              state.filteredEvents.lenght = 0;
              state.filteredEvents.push(... localData);
            }

            if(localStorage.getItem('favEvents')) {
                state.favorites = JSON.parse(localStorage.getItem('favEvents'));
			}

        },
        filteringEvents(state, payload){
            state.currentFilter = payload.filter;
            state.filteredEvents.length = 0;
            if(payload.filter === 'all'){
                state.filteredEvents.push(... state.events);
            } else {
              const filteredList = state.events.filter((event) => event.month === payload.filter);
              state.filteredEvents.push(... filteredList);
            }
        },
        setLoading(state, payload){
            state.isLoading = payload;
        }
    }
});

const app = createApp(App);

app.use(store);
app.use(router);
// app.use(VueOnlineProp);

router.isReady().then(function(){
    app.mount('#app');
});

router.beforeEach((to, from, next) => {
    // console.log('TO : ', to)
    // console.log('FROM : ', from);
    gsap.to('.current-page-name', .5, {y: '50%', autoAlpha: 0, onComplete: function(){
        if(to.name === 'single-event'){
            const event = store.state.events.find(event => event.id === to.params.eventId)
            // console.log(event.title)
            store.state.currentPage = event.title
        } else if(to.name === 'fav') {
            store.state.currentPage = 'Favoris'
        } else {
            store.state.currentPage = 'Concert'
        }
        gsap.to('.current-page-name', .5, {y: 0, autoAlpha: 1})
    }});
    next();
});

And this is my app.vue

<template>
  <PageHeader />
    <router-view v-slot="slotProps">
      <transition :name="transitionName" mode='in-out'>
        <component :is="slotProps.Component"></component>
      </transition>
    </router-view>
  <FooterNav />
  <LoadingScreen v-if="$store.state.isLoading"/>
</template>

<script>
import PageHeader from './components/PageHeader.vue'
import FooterNav from './components/FooterNav.vue'
import LoadingScreen from './components/LoadingScreen.vue'
import gsap from 'gsap';
// import {Power4} from 'gsap';

export default {
  name: 'App',
  components: {
    PageHeader,
    FooterNav,
    LoadingScreen
  },
  data (){
    return {
      transitionName: 'slide-left'
    }
  },
  watch: {
    $route(to) {
      // console.log('TO', to)
      // console.log('FROM', from)
      this.transitionName = to.name === 'home' ? 'slide-right' : 'slide-left'
    } 
  },
  beforeCreate() {
    // console.log('APP BEFORE CREATED')
		this.$store.commit('checkConnectionStatus');
    this.$store.commit('getAndSetData');
    
    if ('ontouchstart' in document.documentElement) {
      document.body.classList.add('touch');
    }
  },
  mounted() {
    const that = this;
    gsap.to('.loading-screen', 1, {autoAlpha: 0, delay: 1, onComplete: function(){
      that.$store.commit('setLoading', false);
    }});
  }
  
}
</script>

Thank you for your time.

Is there someone to help me?

As I said in my original response, you need to wait for your data to exist in your store before you can access it. You are trying to access it before it exists in the store and therefore it is undefined.

beforeCreate() {
  this.$store.commit('getAndSetData');
}

Here you call your api request, but this doesn’t stop the execution of the app and therefore it continues to go through the lifecycle hooks to mount the app.

So at the same time that your request is in flight, your component mounts and the created hook runs

created() {
  const eventId = this.$route.params.eventId;
  const selectedEvent = this.$store.state.events.find(event => event.id === eventId);
}

which is why the selectedEvent here is undefined.

Also, you are using mutations incorrectly. Mutations are synchronous. They should only commit a change, not run logic such as an API request. Asynchronous methods should be run within actions.

I’ve been using actions that commit a mutation but I don’t know how to WAIT in the component (SingleEvent) for the list to be ready, how can I pass the list of events to the SingleEvent component before displaying. I definitely understood the fact that the data is not ready when the page is displaying. So my question is, on the SingleEvent component, how do I set the data, how do I wait? should I use a lifecycle hook or a props or anything else? Should I dispatch again the action when that component is created? Well in short how do I make my SingleEvent component reactive to store data changing? Should I use a watcher? there are a lot of stuff and I’m badly mixing everything in my head.

Here is the code I modified using action instead of mutation, it’s working for the homepage but for the single page, it’s not working. Could you please explain me how to modify this component in order to make it work?

main.js

import 'normalize.css'
import { createApp } from 'vue'
import { createStore } from 'vuex'
import { createRouter, createWebHistory } from 'vue-router'
import axios from 'axios'
import App from './App.vue'
import Home from './components/Home.vue'
import SingleEvent from './components/SingleEvent.vue'
import FavoriteEvents from './components/FavoriteEvents.vue'
import './registerServiceWorker'
import gsap from 'gsap';
//import {Power4} from 'gsap';

const router = createRouter({
    history: createWebHistory(),
    routes: [
        {name: 'home', path: '/', component: Home},
        {name: 'fav', path: '/favoris', component: FavoriteEvents},
        {name: 'single-event', path: '/:eventId', component: SingleEvent}
    ]
});

const store = createStore({
    state(){
        return {
            // dataUrl: 'https://osr-app-2a8b6-default-rtdb.europe-west1.firebasedatabase.app/events.json',
            dataUrl: 'http://localhost:3000/events',
            //dataUrl: 'https://osr-osr20ma32.ideative.io/fr/?json',
            connectionStatus: '',
            currentPage: 'Concerts',
            currentFilter: 'all',
            events: [],
            filteredEvents: [],
            // serieType: [],
            favorites: [],
            isLoading: true
        };
    },
    getters: {
        fullListOfEvents: state => {
          return state.events;
        }
    },
    // getters: {
    //     isOnline: function () {
    //         if(navigator.onLine){
    //           return true;
    //         } else {
    //           return false;
    //         }
    //     }
    // },
    mutations: {
        toggleToFavorites(state, payload){
            //console.log('togglew to fav from MAIN js');
            if(state.favorites.includes(payload.concert)){
                const index = state.favorites.indexOf(payload.concert);
                state.favorites.splice(index, 1);
            } else {
                state.favorites.push(payload.concert);
            }
            localStorage.setItem('favEvents', JSON.stringify(state.favorites));
            console.log(localStorage.getItem('favEvents'));
        },
        checkConnectionStatus(state) {	
            if (navigator.onLine){
                state.connectionStatus = 'online';
            } else{
                state.connectionStatus = 'offline';
            }
        },
        setData(state, payload){
            //console.log(payload.data.data);
            //console.log('MUTATION SET DATA')

            state.events.length = 0;
            state.events.push(... payload.data.data);

            state.filteredEvents.lenght = 0;
            state.filteredEvents.push(... state.events);
            
            localStorage.setItem('osrEvents', JSON.stringify(payload.data.data));

            //console.log('YOYOYOYOY', state.events)
            //console.log('YOYOYOYOY', payload)
            state.isLoading = false;
        },
        filteringEvents(state, payload){
            state.currentFilter = payload.filter;
            state.filteredEvents.length = 0;
            if(payload.filter === 'all'){
                state.filteredEvents.push(... state.events);
            } else {
              const filteredList = state.events.filter((event) => event.month === payload.filter);
              state.filteredEvents.push(... filteredList);
            }
        },
        // setLoading(state, payload){
        //     state.isLoading = payload;
        // }
    },
    actions: {
        getAndSetData(context){
            // context.state.commit('setData');
            // if(state.connectionStatus === 'online'){ // if internet connection, fetch data from porvided API URL
                axios.get(context.state.dataUrl)
                .then(response => {
                    //console.log(response.data)
                  // handle success
                  //console.log(response.data.events)
                  //console.log('RESPONSE : ', response)
                  context.commit('setData', {
                      data: response
                  });

                })
                .catch(function () {
                  // handle error
                  //console.log(error);
                })
                .then(function () {
                  // always executed
                });
            // } else { // Otherwise check if there is a cached version of that data in the localStorage
            //   const localData = JSON.parse(localStorage.getItem('osrEvents'));
            //   state.events.length = 0;
            //   state.events.push(... localData);
            //   state.filteredEvents.lenght = 0;
            //   state.filteredEvents.push(... localData);
            // }

            if(localStorage.getItem('favEvents')) {
                context.state.favorites = JSON.parse(localStorage.getItem('favEvents'));
			}

            
        },
    }
});

const app = createApp(App);

app.use(store);
app.use(router);
// app.use(VueOnlineProp);

router.isReady().then(function(){
    app.mount('#app');
});

router.beforeEach((to, from, next) => {
    // console.log('TO : ', to)
    // console.log('FROM : ', from);
    gsap.to('.current-page-name', .5, {y: '50%', autoAlpha: 0, onComplete: function(){
        if(to.name === 'single-event'){
            // console.log(to.params.eventId)
            // const event = store.state.events.find(event => event.id === to.params.eventId)
            // console.log(store.state.events);
            // store.state.currentPage = event.title
        } else if(to.name === 'fav') {
            store.state.currentPage = 'Favoris'
        } else {
            store.state.currentPage = 'Concert'
        }
        gsap.to('.current-page-name', .5, {y: 0, autoAlpha: 1})
    }});
    next();
    
});

// router.beforeRouteEnter(()=>{
//     console.log('beforeRouteEnter')
// })

// router.beforeEach((to, from, next) => {
//     console.log(to, from, next)
//     next();
// });

App.vu

<template>
  <PageHeader />
    <router-view v-slot="slotProps">
      <transition :name="transitionName" mode='in-out'>
        <component :is="slotProps.Component"></component>
      </transition>
    </router-view>
  <FooterNav />
  <transition name="fade">
    <LoadingScreen v-if="$store.state.isLoading" />
  </transition>
</template>

<script>
import PageHeader from './components/PageHeader.vue'
import FooterNav from './components/FooterNav.vue'
import LoadingScreen from './components/LoadingScreen.vue'
// import gsap from 'gsap';
// import {Power4} from 'gsap';

export default {
  name: 'App',
  components: {
    PageHeader,
    FooterNav,
    LoadingScreen
  },
  data (){
    return {
      transitionName: 'slide-left'
    }
  },
  watch: {
    $route(to) {
      // console.log('TO', to)
      // console.log('FROM', from)
      this.transitionName = to.name === 'home' ? 'slide-right' : 'slide-left'
    } 
  },
  beforeCreate() {
    // console.log('APP BEFORE CREATED')
		this.$store.commit('checkConnectionStatus');
    //this.$store.commit('getAndSetData');
    this.$store.dispatch('getAndSetData')

    if ('ontouchstart' in document.documentElement) {
      document.body.classList.add('touch');
    }
  },
  // mounted() {
  //   const that = this;
  //   gsap.to('.loading-screen', 1, {autoAlpha: 0, delay: 1, onComplete: function(){
  //     that.$store.commit('setLoading', false);
  //   }});
  // }
  
}
</script>

SingleEvent.vue

<template>
    <div :class="singleEventClass">
        <div class="page__content">
            <SingleCta :id="$route.params.eventId"/>
            <SingleHeader 
                :series="series"
                :title="title"
                :day="day"
                :time="time"
                :date="date"
                :where="where"
                :people="people"
            />
            <PartnerList :partners="partners"/>
            <GalleryCarousel :images="gallery" />
            <TheProgram 
                :people-list="people"
                :program="program"
                :description="description"
                :ad="adProgram"
            />  
            <DropdownList :dropdowns="dropDowns" />
        </div>
    </div>
</template>
<script>
    import SingleCta from './SingleCta.vue';
    import SingleHeader from './SingleHeader.vue';
    import PartnerList from './PartnerList.vue';
    import GalleryCarousel from './GalleryCarousel.vue';
    import TheProgram from './TheProgram.vue';
    import DropdownList from './DropdownList.vue';
    
    export default {
        components: {
            SingleCta,
            SingleHeader,
            PartnerList,
            GalleryCarousel,
            TheProgram,
            DropdownList,
        },
        data() {
            return {
                singleEvent: this.selectedEvent,
                title: '',
                series: '',
                day: '',
                time: '',
                date: '',
                where: '',
                dropDowns: [],
                gallery: [],
                partners: [],
                people: [],
                program: '',
                description: '',
                adProgram: {},
                txtColor: '',
                bgColor: ''
            }
        },
        methods: {
            setData: function (thisEvent) {
                this.title = thisEvent.title;
                this.series = thisEvent.series;
                this.day= thisEvent.day;
                this.time= thisEvent.time;
                this.date= thisEvent.date;
                this.where = thisEvent.where;
                this.dropDowns = thisEvent.content.dropDowns;
                this.gallery = thisEvent.content.gallery;
                this.partners = thisEvent.content.partners;
                this.people = thisEvent.content.people;
                this.program = thisEvent.content.program;
                this.description = thisEvent.content.description;
                this.adProgram = thisEvent.content.adProgram;
                this.txtColor = thisEvent.txtColor;
                this.bgColor = thisEvent.bgColor;
            }
        },
        computed: {
            singleEventClass(){
                return 'page single-event ' + 'single-event--' + this.txtColor + ' ' + 'single-event--' + this.bgColor
            },
            selectedEvent(){
                //return this.$store.state.events.find(event => event.id === this.$route.params.eventId)
                return this.$store.getters.fullListOfEvents.find(event => event.id == this.$route.params.eventId)
            }
        },
        // watch:{
        //     selectedEvent(event) {
        //         //console.log(this.selectedEvent)
        //         console.log(event)
        //         this.setData(event)
        //         // console.log('EVENT CHANGED')
        //     },
        // },
        created(){
            console.log(this.selectedEvent)
            this.$store.dispatch('getAndSetData');
            this.setData(this.selectedEvent);
        }
        // created() {
        //     this.$store.dispatch('getAndSetData')

        //     if ('ontouchstart' in document.documentElement) {
        //         document.body.classList.add('touch');
        //     }
        // },
        
    }
</script>

Thank you

I’m sure it’s something that most of the app does so I guess they must be a “how to” somewhere on the web. I mean a list of articles page and the single article page, this must be super easy to do, how do I wait for the data and when it’s ready then use it in a child component, I’m super struggling on that. Is there some kind of tutorial or something somewhere? PLEASE HELP, it’s been 5-6 days I’m stuck on that! just on that! Is there some kind of forum on the web specialised on vue js, where I can get help?

Thank you

Are there some people active on this forum? Could someone point me a place where I could get help?

Send off the action to get the data…

created(){
  this.$store.dispatch('getAndSetData');
  // I'm not sure why you set all this data when it's already returned by the computed
  // this.setData(this.selectedEvent);
}

Within your template, use a v-if against the computed property to check if the data exists. If it doesn’t exist, it will not render the component. Once the event exists, the component and underlying children will render.

<div :class="singleEventClass" v-if="selectedEvent">
</div>
1 Like

:slight_smile: but how do I set the data then? That’s actually the question

like this?

data() {
    return {
        singleEvent: this.selectedEvent,
        title: this.selectedEvent.title,
        series: this.selectedEvent.serie,
        day: this.selectedEvent.day,
        time: this.selectedEvent.time,
        date: this.selectedEvent.date,
        where: '',
        dropDowns: [],
        gallery: [],
        partners: [],
        people: [],
        program: '',
        description: '',
        adProgram: {},
        txtColor: '',
        bgColor: ''
    }
},

Because like this I have :

SingleEvent.vue?b76f:46 Uncaught (in promise) TypeError: Cannot read property 'title' of undefined

So that’s why I was using a method to set the data.
Now it’s not working on navigation AND on page reload. It’s not working anymore. At all.

Thank you @JamesThomson James for your time, I managed to fix that, so instead of using data I’m passing directly the data to the sub components like this :

<template>
    <div :class="singleEventClass" v-if="selectedEvent">
        <div class="page__content">
            <SingleCta :id="$route.params.eventId"/>
            <SingleHeader 
                :series="selectedEvent.series"
                :title="selectedEvent.title"
                :day="selectedEvent.day"
                :time="selectedEvent.time"
                :date="selectedEvent.date"
                :where="selectedEvent.where"
                :people="selectedEvent.content.people"
            />
            <PartnerList :partners="selectedEvent.content.partners"/>
            <GalleryCarousel :images="selectedEvent.content.gallery" />
            <TheProgram 
                :people-list="selectedEvent.content.people"
                :program="selectedEvent.content.program"
                :description="selectedEvent.content.description"
                :ad="selectedEvent.content.adProgram"
            />  
            <DropdownList :dropdowns="selectedEvent.content.dropDowns" />
            <VideoBlock :videoUrl="`https://www.youtube.com/watch?v=cSzzEgeI2_E`"/>
        </div>
    </div>
</template>

I don’t understand why using the data is not working tho!

You can use data, it’s just redundant when you already have it stored in your Vuex store. The problem wasn’t to do with data or the computed property. It was to do with the component rendering before it had that data. This is what using the v-if solves.

1 Like

You can directly reference data in template, also use computed to indirectly reference data, or manually watch the data changes through the watch options. Re-rendering can be triggered when the data changes.