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>
Advertisement
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>