Changing the location of an ArcGIS map with a click event in a Vue application

I am attempting to dynamically update a map to display my current location using Vue. I have created an onClick event that updates the props and sends them to my map component. To trigger a re-render of the map component when the data changes, I am utilizing a :key. However, based on the esri/arcgis example, it seems like I may need to rebuild the map completely. If anyone has insight into whether this approach is incorrect, please let me know.

For reference, here is the starting documentation for using ArcGIS with VUE js:

I have encountered an issue where the map appears to render again but then remains blank. Could this be due to some persistence of the component after forcing it to render?

Below is the code snippet from my app.vue:

<template>
    <div id="app">
        <web-map v-bind:centerX="lat" v-bind:centerY="long" ref="mapRef"/>

        <div class="center">
          <b-button class="btn-block" @click="getLocation" variant="primary">My Location</b-button>
        </div>
    </div>


</template>

<script>
import WebMap from './components/webmap.vue';

export default {
    name: 'App',
    components: { WebMap }, 
    data(){
      return{
        lat: -118,
        long: 34,
      }
    },
    methods:{

      showPos(pos){
        this.lat = pos.coords.latitude
        this.long = pos.coords.longitude

        this.$refs.mapRef.updateCoordinates()
        console.log('new location',this.lat,this.long, this.$refs)   
      },


      getLocation(){
        if (navigator.geolocation) {
              navigator.geolocation.getCurrentPosition(this.showPos);
          } else { 
            console.log("Geolocation is not supported by this browser.");
          }
      },

    },
};
</script>

Here is the corresponding code snippet from my map component:

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

<script>
import { loadModules } from 'esri-loader';

export default {
  name: 'web-map',
  props:['centerX', 'centerY'],
  data: function(){
    return{
      X: this.centerX,
      Y: this.centerY,
      view: null
    }
  },
  mounted() {
    console.log('new data',this.X,this.Y)

    // lazy load the required ArcGIS API for JavaScript modules and CSS
    loadModules(['esri/Map', 'esri/views/MapView'], { css: true })
    .then(([ArcGISMap, MapView]) => {
      const map = new ArcGISMap({
        basemap: 'topo-vector'
      });

      this.view = new MapView({
        container: this.$el,
        map: map,
        center: [this.X,this.Y],   ///USE PROPS HERE FOR NEW CENTER
        zoom: 8
      });
    });
  },
  beforeDestroy() {
    if (this.view) {
      // destroy the map view
      this.view.container = null;
    }
  },
  methods:{
    updateCoordinates(){
        this.view.centerAt([this.X,this.Y])
      }
  }

};

</script>

Answer №1

It seems the key being passed as a prop to web-map may not be necessary as it's not utilized within the component.

An alternative approach could be to forcefully update the component like so:

<web-map v-bind:centerX="lat" v-bind:centerY="long" ref="mapRef" />
this.refs.mapRef.$forceUpdate()

This method ensures the entire component is updated forcibly. However, there might be a more efficient solution available. Rather than re-rendering the complete component, which would require recreating the map, you could keep the component active and trigger an event to update the coordinates instead.

According to the documentation at , you can relocate the map's center using the centerAt function.

In this scenario, the map component could feature a method such as:

updateCoordinates(coord){
  this.view.centerAt(coord)
}

You can then invoke this method from the parent component with:

this.refs.mapRef.updateCoordinates(newCenter)

I hope this information proves helpful. Please let me know if you make any progress!

Answer №2

In my opinion, you could experiment with using the Watch function in conjunction with setInterVal() to create a continuous loop that checks your location every second.

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

Tips for using Howler library in React to automatically play audio upon loading the page

I'm troubleshooting why the audio on my webpage won't start playing when the page loads, and instead only plays after a mouse click triggers an event. The audio works fine but I want it to automatically play as soon as the page is loaded. import ...

Guide on organizing users into groups and filtering them using Firestore's reference field type

I currently manage a small group of employees with plans to expand in the future. To streamline operations, I am looking to implement a grouping feature that allows users to sort employees based on their assigned groups. Although I thought about using the ...

The information displayed in my Google snippet does not match the content of the intended URL

It may seem a bit confusing, so to clarify, here is an example: When you click the +1 button on this page, the snippet will display the text and URL from that specific page. However, in my case, the snippet displays text from the homepage URL instea ...

Sequencing numerous promises (managing callbacks)

I am encountering some challenges with promises when it comes to chaining multiple ones. I'm having difficulty distinguishing how to effectively utilize promises and their differences with callbacks. I've noticed that sometimes callbacks are trig ...

Can the concept of partial class be used in an AngularJS controller?

Is it possible to organize code into groups using partials in angularjs? The issue is that my controller has become too cluttered with a lot of code for different methods and functionalities, making it difficult to read. I want to maintain the same contro ...

Losing scope of "this" when accessing an Angular2 app through the window

My Angular2 app has exposed certain methods to code running outside of ng2. However, the issue arises when calling these methods outside of ng2 as the context of this is different compared to when called inside. Take a look at this link to see what exactl ...

Is there a way to prevent Backbone.js from deleting surrounding elements with 'default' values?

Trying to articulate this question is a challenge, so please let me know if further clarification is needed. As I am new to backbone.js, my inquiry may seem basic. My goal is to utilize backbone to efficiently generate graphs using the highcharts library. ...

How to make an entire video clickable on Android for seamless playback?

I have implemented an HTML5 video in my mobile web application. Currently, users need to click the small play icon at the bottom left of the video to start playing it. Is there a way to make the entire video clickable so it plays when clicked anywhere on t ...

Having trouble understanding why adding raw HTML is yielding different results compared to generating HTML using jQuery

I need assistance with two jsFiddles: http://jsfiddle.net/kRyhw/3/ http://jsfiddle.net/kBMSa/1/ In the first jsFiddle, there is code that adds HTML to my ul element, including an 'X' icon in SVG format. Attempting to recreate this functionali ...

Obtaining serverTime from a webpageWould you like to learn

Is it possible to retrieve the serverTime using jquery ajax functions like $.get() or $.post()? I am looking to store this serverTime in a variable that can be utilized later on in javascript. You can access the webpage at: To use the get and post functi ...

Improve the functionality of select[multiple] to allow for single-click modifications without the need for CMD/CTRL

I am attempting to modify the default functionality of a select element so that clicking once on its options changes their selected state. Essentially, I want to eliminate the confusing requirement of holding down shift/ctrl to select multiple options. I ...

What could be causing the remove attribute API to not function properly only for the "is" attribute?

var divElement = document.createElement("div"); var innerHTMLText = "<div id='issue' is='if'> some content </div>"; divElement.innerHTML = innerHTMLText; document.body.appendChild(divElement); var newDivElement = document.qu ...

Creating a dynamic hyperlink variable that updates based on user input

I am attempting to create a dynamic mailto: link that changes based on user input from a text field and button click. I have successfully achieved this without using the href attribute, but I am encountering issues when trying to set it with the href attr ...

Ways to make a button blink using AngularJS

Currently working on an AngularJS SPA application where a button is present in the front-end HTML page. When this button is clicked, it triggers an operation which takes some time to complete. I want to inform the user that the operation is still in prog ...

How to import a module from the root path using TypeScript in IntelliJ IDEA

Despite this topic being widely discussed, I still struggle to understand it. Below is my tsconfig.json file: { "compilerOptions": { "module": "commonjs", "target": "es2017", "sourceMap": true, "declaration": true, "allowSyntheticDe ...

Images failing to load in jQuery Colorbox plugin

I am having an issue with the Color Box jQuery plugin. You can find more information about the plugin here: Here is the HTML code I am using: <center> <div class='images'> <a class="group1" href="http://placehold.it/ ...

Combining two elements in a React application

Having a collection of assets and their quantities: const bag = { eth: 50, btc: 30, kla: 10, set: 5, ova: 5 }; const assetList = { eth: { name: "Ethereum", icon: "urlhere", colour: "#030", text: "light&q ...

When the LI element is clicked, it triggers the display of another LI element without affecting the rest of the

New to the web development scene and trying to figure out how to create a collapsible text feature using HTML, JavaScript, and JQuery. I've got the styling down but struggling with the scripting part. Here's an example of what I'm trying to ...

Revamping reactivity for component props in Vue 3

Within my EditTransaction component, I am calling it in the following manner: <edit-transaction v-if="editableTransaction.id === transaction.id" :key="'transaction'+transaction.id+etcount" :class="{'bg ...

I can't figure out why I'm receiving a TypeError stating that onSuccess is not a function within my AngularJS service

Utilizing an angularjs service that utilizes restangular for API calls. angular.module('app.userService', []) .factory('userService', ['localStorageService', '$rootScope', 'Restangular', func ...