My web application, built with Laravel / Vue JS, includes a google map component and a Vuetify data-table component. The Vue instance also features a computed property that calculates points for the Google Map based on another computed property from the Vuetify data-table.
Code snippet of Vue Components in view blade:
<v-data-table :ref="model + 'Table'" v-model="selected" :headers="headers" :items="collection" :pagination.sync="pagination" select-all item-key="id" class="elevation-1" ></v-data-table>
<google-map v-if="mapPoints.length" class="google-map" :markers="mapPoints"></google-map>
Vue Instance code:
var app = new Vue({
el: '#app',
mixins: [ crudFunctionsMixin, adminLayoutMixin ],
data: () => ({
}),
computed: {
mapPoints: function() {
return this.calcPoints(this.$refs.prospectTable.filteredItems);
}
},
methods: {
calcPoints(items) {
let myPts = [];
let i = 0;
items.forEach(function(prospect) {
if(prospect.latitude && prospect.longitude) {
myPts.push({
id: prospect.id,
position: {
lat: prospect.latitude,
lng: prospect.longitude
},
index: i++,
title: prospect.address + ", " + prospect.city + ", " + prospect.zip,
icon: "/img/numberedMapIcons/number_" + prospect.id + ".png"
});
}
});
return myPts;
}
}
});
The current setup throws a type error:
TypeError: Cannot read property 'filteredItems' of undefined
This error occurs because the computed property within the Vuetify data-table component has not been calculated when the GoogleMap component tries to access it.
I attempted to modify the computed property to return an empty array if "$refs.prospectTable.filteredItems" is still undefined, but this method proved to be ineffective as the computed property only gets evaluated once.
Why does the "mapPoints" computed property not update each time "$refs.prospectTable.filteredItems" changes?
An update was suggested to use a $watch variable inside the mounted() lifecycle hook instead of relying on a computed property:
mounted() {
this.$watch(
() => {
return this.$refs.prospectTable.filteredItems;
},
(items) => {
this.mapPoints = this.calcPoints(items);
}
);
}