Vue 3 does not maintain derived property values when assigning them to an object value

I have been facing a challenge while trying to set up an object for the Ionic Capacitor Google Maps API in order to configure the map upon creation. The issue I am encountering is that the value of the reference I am using is not persistent and keeps reverting to its default value. Despite spending several days attempting to resolve this issue, I have not been successful. I would greatly appreciate any assistance in demonstrating how to address this problem. Below is the code snippet:

<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

Answer №1

mapConfig lacks reactivity.

A simple adjustment should make it functional:

mapConfig = computed(() => ({
  center: {
    lat: centerLat.value,
    lng: lng.value
  },
  zoom: 10,
}))

Personally, I prefer this approach:

<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() {
  // initialize map logic here...
}
onMounted(() => getLocation().then(initMap))

// make variables accessible in the template without 'state.' prefix:
const { lat, lng, mapConfig } = toRefs(state)
</script>

I find this method cleaner and more straightforward to manage (especially for future expansions).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

`Browser Extension Compatibility``

I am currently working on developing a TypeScript extension that is compatible with all major browsers. I have come across the package https://www.npmjs.com/package/web-ext-types which I have integrated into my package.json file. While coding in TypeScrip ...

Similar to the "beforesend" functionality in JavaScript, there is a corresponding feature

When attempting to post a comment in my ionic app using the Wordpress api, I encountered error 401 (unauthorized) indicating that the Wordpress api does not recognize me as logged in. This is the code I am using: postComment(params?: any) { let nonce = l ...

What are the distinctions between generic and discriminated types?

Hi there, I've been thinking of an idea but I'm not sure how to implement it or if it's even possible. Is there a way to create a type SomeType where the first property can be any value from the set T, but the second property cannot be the ...

The border of the Material UI Toggle Button is not appearing

There seems to be an issue with the left border not appearing in the toggle bar below that I created using MuiToggleButton. Any idea what could be causing this? Thank you in advance. view image here view image here Just a note: it works correctly in the ...

Error encountered while building with Next.js using TypeScript: SyntaxError - Unexpected token 'export' in data export

For access to the code, click here => https://codesandbox.io/s/sweet-mcclintock-dhczx?file=/pages/index.js The initial issue arises when attempting to use @iconify-icons/cryptocurrency with next.js and typescript (specifically in typescript). SyntaxErr ...

How to pass data to a multiselect component in VueJS 3 within a child component

Trying to pass data from the parent component to the child component's multiselect drop-downs has been a bit challenging. While I have four dropdowns, for this example I've included just one. Duplicating the code from the parent to child for &ap ...

Eliminate the loading screen in Ionic 2

Within my app, there is a button that triggers the opening of WhatsApp and sends a sound. Attached to this button is a method that creates an Ionic loading component when clicked. The issue I am facing lies with the "loading.dismiss()" function. I want the ...

Tips for accurately typing a "Type Mapping" function

In my code, I have a specific type designed for a function that takes one type I as input and returns another type O as output. Here is how it currently looks: export interface IFunctionalMapping<I, O, K extends keyof O> { [prop: Extract<O[K], ...

Deleting the First Item from an Array in Typescript using Angular

Clicking my Button in .html <button (click)="deleteFirst()">Delete First</button> My array setup and removal function in .ts: people = [ {first: "Tom", last: "Brown"}, {first: "Ben", last: &qu ...

The custom validator in Material2 Datepicker successfully returns a date object instead of a string

Im currently working on developing a unique custom validator for the datepicker feature within a reactive form group. Within my code file, specifically the .ts file: form: FormGroup; constructor( private fb: FormBuilder, ...

What is the best way to implement a dynamic mask using imask in a React

I have a question regarding the implementation of two masks based on the number of digits. While visually they work correctly, when I submit the form, the first mask is always selected. How can I resolve this issue? My solution involves using imask-react ...

Guide on bringing in Javascript file into your Ionic/Angular application

Within my Ionic 2 application, I have incorporated three.js along with a PLYLoader extension for three.js (accessible here: https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/PLYLoader.js) Integrating three.js is straightforward by includi ...

Ways to imitate an export default function

//CustomConfigurator.ts export default function customizeConfig(name: string): string { // add some custom logic here return output; } //CustomUtility.ts import customizeConfig from './CustomConfigurator'; export default class CustomUtility ...

The custom layout for Nuxt 3 is encountering an error, displaying an error message

While attempting to implement a customized layout in my Nuxt 3 project, I encountered an issue where the layout was not functioning correctly. The console displayed the following message: Invalid layout test_layout selected No other errors were reported ...

Ensure the object is not null with this Object type guard

Is there a way to create a type guard for an object directly in TypeScript? I've written a function to check any input: export function isObject(input: any) :input is Record<string,any> { return (input !== null) && (typeof input == ...

Jetbrains WebStorm has issued a caution about experimental support for decorators, noting that this feature is in a state of flux and may

No matter how long I've been searching, I can't seem to get rid of this warning even after setting the experimentalDecorators in my tsconfig file. I'm currently working on an Ionic project with Angular, using webstorm by JetBrains as my IDE. ...

Disabling dynamic color updates upon refresh

I am currently using chartjs and I want to generate new random colors each time the page is refreshed. However, I need these colors to remain fixed and not change after a page refresh or reload. Below is the function I am working with: getRandomRgb() { ...

ReactNative: When attempting to navigate, a TypeError occurred - this.props.navigation.navigate is not a function

It's confusing to see how this issue is occurring, even though all props have been properly typed. The goal is to pass the navigator to the bottom bar component in order to navigate onPress. Initially, I define the props interface: export interface B ...

Filtering the data in the table was successful, but upon searching again, nothing was found. [Using Angular, Pagination, and

Having a table with pagination, I created a function that filters the object and displays the result in the table. The issue arises when I perform a new search. The data from the initial search gets removed and cannot be found in subsequent searches. Bel ...

Is there a way to modify the dimensions of this container? (CSS)

After performing a search and clicking on a result, a white bubble pops up on the map. I am looking to use CSS to make this bubble smaller as it is currently too large. Can anyone provide guidance on how to achieve this? ...