'Unable to send props in vuejs

I am trying to send 2 props to my navbar component but it does not receive the data.

Here is what I get instead of my data:

one

Code:

Front.vue (upper template)

<template>
    <front-nav :menus="menus" :settings="settings"></front-nav>
    <router-view :key="$route.fullPath"></router-view>
    <front-footer></front-footer>
</template>

<script>
    import frontNav from './frontNavBar.vue';
    import frontFooter from './frontFooter.vue';
    export default {
        name: 'front',
        data(){
            return {
                settings: {
                    name: '',
                    favicon: '',
                    logo: '',
                },
                menus: [],
            }
        },
        components: {
            frontNav,
            frontFooter
        },
        mounted() {
            this.getData();
        },
        methods: {
            getData() {
                axios.get('/api/general')
                .then(response => {
                    this.settings = response.data.settings[0];
                    this.menus = response.data.menus;
                })
                .catch(function (error) {
                    console.log('error', error);
                });
            }
        },
    }
</script>

Nabar component (receiving props)

<template>
    <div>data goes here...</div>
</template>


<script>
    export default {
        name: 'frontNav',
        props: ['settings', 'menus'],
        data() {
            //
        },
        mounted() {
            console.log('settings: ', this.settings)
            console.log('menus: ', this.menus)
        },
        methods: {
            //
        }
    }
</script>

results of console.log('settings: ', this.settings) and console.log('menus: ', this.menus) are in image above.

Any idea?



Solution 1:[1]

You are mounting front-nav before getData() runs and returns the appropriate response, hence empty props. You should wait for getData() to complete before mounting front-nav.

You could do something like:

  1. Use <Suspense>

  2. Use <front-nav v-if="menus" :menus="menus" :settings="settings"> or something appropriate that you know will have a value when getData() returns a response and you have meaningful value.

Solution 2:[2]

Solved

I've added childDataLoaded: false, to my Front.vue component and set it as true when data are loaded so it works now, here is how:

<template>
    <template v-if="childDataLoaded"> // <-- here
        <front-nav :menus="menus" :settings="settings"></front-nav>
    </template>
    <router-view :key="$route.fullPath"></router-view>
    <front-footer></front-footer>
</template>

<script>
    import frontNav from './frontNavBar.vue';
    import frontFooter from './frontFooter.vue';
    export default {
        name: 'front',
        data(){
            return {
                childDataLoaded: false, // <-- here
                settings: {
                    name: '',
                    favicon: '',
                    logo: '',
                },
                menus: [],
            }
        },
        components: {
            frontNav,
            frontFooter
        },
        mounted() {
            this.getData();
        },
        methods: {
            getData() {
                axios.get('/api/general')
                .then(response => {
                    this.settings = response.data.settings[0];
                    this.menus = response.data.menus;
                    this.childDataLoaded: true, // <-- here
                })
                .catch(function (error) {
                    console.log('error', error);
                });
            }
        },
    }
</script>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 mafortis