I am trying to create an object to use in the Ionic Capacitor Google Maps API to configure the map at it's creation. Unfortunately, the value of the ref I use is not persistent and reverts to its default value. I have been trying to solve this issue for days with no success. Any help in showing how to make this work would be much appreciated. My code:
<script setup lang="ts">
import { computed, ref, onMounted } from "vue";
import { Geolocation } from "@capacitor/geolocation";
const currPos = ref<any | null>(null);
const lat = ref<number>(1);
const lng = ref<number>(2);
const getLocation = async () => {
console.log("got getLocation event");
currPos.value = await Geolocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 20000,
});
lat.value = currPos.value.coords.latitude;
lng.value = currPos.value.coords.longitude;
};
const centerLat = computed(() => (lat.value ? lat.value : 3));
const mapConfig = {
center: {
// The initial position to be rendered by the map
// lat: 32.78025, // this works
// lng: -117.19335, // this works
lat: centerLat.value as number, // not working, is 1
lng: lng.value as number, // not working, is 2
},
zoom: 10,
};
const logLocData = () => {
console.log("Latitude", lat.value); // shows correct number for lat
console.log("Longitude", lng.value); // shows correct number for lng
console.log("Center Latitude", centerLat.value); // shows correct number for centerLat
console.log("MapCofig", mapConfig); // wrong, shows center and 1 for lat and 2 for lng
console.log("MapCofig Latitude", mapConfig.center.lat); // wrong, shows 1 for lat
console.log("MapCofig Longitude", mapConfig.center.lng); // wrong, shows 2 for lng
};
onMounted(() => {
console.log("mounted");
getLocation();
});
</script>
Console log:
mounted
got getLocation event
Latitude 32.7822162
Longitude -117.1852825
Center Latitude 32.7822162
MapCofig {center: {…}, zoom: 10}
MapCofig Latitude 1
MapCofig Longitude 2
mapConfig
is not reactive.
With minimal changes, this should work:
mapConfig = computed(() => ({
center: {
lat: centerLat.value,
lng: lng.value
},
zoom: 10,
}))
But I would personally go with this:
<script setup lang="ts">
import { computed, toRefs, onMounted, reactive } from "vue"
type State = {
lat: number
lng: number
centerLat: number
mapConfig: {
center: {
lat: number
lng: number
}
zoom: number
}
currPos: {
coords: {
latitude: number
longitude: number
}
} | null
}
const state: State = reactive({
currPos: null,
lat: computed(() => state.currPos?.coords.latitude || 1),
lng: computed(() => state.currPos?.coords.longitude || 2),
centerLat: computed(() => state.lat || 3),
mapConfig: computed(() => ({
center: {
lat: state.centerLat,
lng: state.lng
},
zoom: 10
}))
})
const getLocation = async () => {
state.currPos = await Geolocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 20000
})
}
const initMap() {
// init map here...
}
onMounted(() => getLocation().then(initMap))
// expose stuff to template, if you don't want the `state.` prefix:
const { lat, lng, mapConfig } = toRefs(state)
</script>
I find it cleaner and easier to work with/follow (I'm guessing you'll be expanding it).