VUE JS passing object to children after mounted

Tags: ,



I have three vue components. One is the page listing, it includes a filter and a list. When the page listing component is rendering, it needs to parse some JSON and passing that object into the filter component. Where I see that there is a problem is that the mounted script is running after the filter component has been rendered, therefore, no object has been passed inside of the filter to render, how do i bypass that ? I have checked the vue cycle but I cannot for the life of me figure out what the problem is.

On the filter component, when I output {{test}} it shows the right text ‘yayaya’ because its a string, and it’s not passing an object that needs to be manipulated. Why is it that when I output {{dataTagGroups}} on the filter component it returns nothing, it’s empty.

LISTING PAGE COMPONENT

   <template>
<div>
    <section class="mega-filter js-mega-filter">

        <mega-filter
            :dataEndpoint="dataEndpoint"
            :dataTagGroups='dataTagGroups'
            :dataSortOptions='dataSortOptions'
            test="yayaya"
            v-cloak
        >
            <!-- label for sort filter -->
            <template slot="sortLabel">Sort</template>
            <template slot="sortLabelMobile">Sort by</template>
        </mega-filter>

   
    </section>
    </div>
</template>

<script>
    import listingcards from '../listing-cards/_listing-cards.vue';
    import megafilter from '../megaFilter/_mega-filter.vue';
    import axios from 'axios';
    export default {
        name: 'listing-cards-list',
        components: {
        'mega-filter': megafilter
        },
        data() {
            return {
                dataEndpoint: '',
                dataTagGroups: {},
                dataSortOptions: {},
                dataNumItems: '',
                dataPageSize: ''
                
            };
        },
        props: {
           
        },
        directives: {
            
        },
        methods: {
           
        },
        mounted() {
            
            
                this.dataEndpoint = this.$el.attributes['data-endpoint-url'] ? this.$el.attributes['data-endpoint-url'].value : null;
            console.log(this.dataEndpoint)
                // set tagGroups options
                const tagGroups = this.$el.attributes['data-tag-options'] ? this.$el.attributes['data-tag-options'].value : null;
                if (tagGroups) {
                    try {
                        this.dataTagGroups = JSON.parse(tagGroups)['tagGroups'];
                    } catch(err) {
                        console.error('Error parsing sort options');
                    }
                }
                console.log(this.dataTagGroups)
                // set sort options
                const sortOptions = this.$el.attributes['data-sort-options'] ? this.$el.attributes['data-sort-options'].value : null;
                if (sortOptions) {
                    try {
                        this.dataSortOptions = JSON.parse(sortOptions)['sortOptions'];
                    } catch(err) {
                        console.error('Error parsing sort options');
                    }
                }
                 console.log(this.dataSortOptions)

            
        }
    }
</script>

FILTER COMPONENT

<template>
    <div class="mega-filter__container l-padding">

        {{dataEndpoint}}
 
    </div>  
</template>

<script>
import { mixin as clickedOutsideDrawer } from 'vue-on-click-outside';
import axios from 'axios';


export default {
    name: 'mega-filter',
    data() {
        return {
            
            dataNumItems: '',
            dataPageSize: '',
            tagFilters: [],
            sortByFilters: [],
            
            url: '',
            ...CONFIG
        }
    },

    props: {
          dataEndpoint: '',
            dataTagGroups: {},
            dataSortOptions: {},
            test:''
    },

    mounted() {
       
    },
    methods: {
      
    }
}
</script>

Answer

You could initially set your dataTagGroups and dataSortOptions in the data as null and only display the filter if those aren’t null anymore.

 data() {
   return {
    dataEndpoint: '',
    dataTagGroups: null,
    dataSortOptions: null,
    dataNumItems: '',
    dataPageSize: ''
 },

in your template you can then use v-if to only render the filter if those conditions are met.

<section class="mega-filter js-mega-filter">
  <mega-filter
    v-if="dataEndpoint && dataTagGroups"
    :dataEndpoint="dataEndpoint"
    :dataTagGroups='dataTagGroups'
    data-tag-name=""
    :dataSortOptions='dataSortOptions'
    data-sort-name=""
    data-sort-direction-name=""
    data-sort-direction-value=""
    data-facet-options=""
    data-num-items="10"
    data-page-size="5"
    data-language=""
    test="yayaya"
    v-cloak
  >
    <!-- label for sort filter -->
    <template slot="sortLabel">Sort</template>
    <template slot="sortLabelMobile">Sort by</template>
  </mega-filter>
  <div v-else>
    Data not ready yet... Loading...
  </div>
</section>



Source: stackoverflow