Looking for a way to automatically update a map within a Vue component

My component successfully:

  • Receives a string from a sibling input component via the global Bus method in created() => works
  • Manipulates the string into lat/lng coordinates via geoDecoding() => works
  • Resolves promise result coordinates, sets data, also via geoDecoding() => works
  • Attempts to refresh showMap() with changed data after an event is fired => does not work :(

Please note that I have props (commented out) with hardcoded defaults just to check showMap() with those values, and it works.

  • I have set a debugger on showMap() and noticed that latitude and longitude are not set, even though I set them under created() when invoking geoDecoding()

I would like showMap() to refresh every time an event is fired, receiving refreshed data from this.latLong.latitude / this.latLong.longitude to correctly instantiate the map according to those new values. Currently, with this code instance, showMap() instantiates a map but remains empty because it's not receiving the lat/lng from geoDecoding().

Code:

<template>
    <div class="map-container" :id="theMap"></div>
</template>

<script>
    import { Bus } from "../main";

    export default {
        name: "GoogleMapsContainer",
        data() {
            return {
                theMap: "map-for-" + this.name,
                location: '',
                latLong: {
                    latitude: '',
                    longitude: ''
                },
            }
        },
        props: {
            name,
            // 'latitude': {
            //     type: Number,
            //     default: function () {
            //         return 39.50
            //     }
            // },
            // 'longitude': {
            //     type: Number,
            //     default: function () {
            //         return -98.35
            //     }
            // },
            // 'zoom': {
            //     type: Number,
            //     default: function () {
            //         return 4
            //     }
            // }
        },
        methods: {
            showMap() {
                debugger;
                this.map = new google.maps.Map(document.getElementById(this.theMap), {
                    center: {lat: this.latLong.latitude, lng: this.latLong.longitude},

                    zoom: this.zoom
                });
            },
            geoDecoding() {
                let geocoder = new google.maps.Geocoder();
                let theLocation = this.location;
                let latLong = this.latLong;

                    return new Promise(function (resolve, reject) {
                        geocoder.geocode({'address': (theLocation ? theLocation : 'canada')}, function (results, status) {
                            console.log(results);
                            if (status === google.maps.GeocoderStatus.OK) {
                                console.log(results[0].geometry.location.lat(), results[0].geometry.location.lng());
                                latLong.latitude = results[0].geometry.location.lat();
                                latLong.longitude = results[0].geometry.location.lng();
                            } else {
                                reject(status);
                            }
                        });
                    });
            }
        },
        mounted() {
            //this.geoDecoding();
            this.showMap();

        },
        created() {
            this.geoDecoding();
            Bus.$on('passLocation', (input) => {
                this.location = input;
                this.geoDecoding();
            });
        },


    }
</script>

<style scoped>
    .map-container {
        width: 80vw;
        margin: 5vh auto;
        height: 50vh;
        background: fuchsia;
    }
</style>

Answer №1

For proper functionality, it is recommended to implement a watcher for the latLong property:


watch: {
  latLong: {
    handler: function(newValue, oldValue) {
      this.displayMap();
    },
    deep: true
  }
},

Answer №2

I came across a solution using Google's API code that worked well for me:

panTo(<your-lat-lng-coords>);

To integrate this into your code, I implemented it during the async call.

The function in my promise is within methods:{geoDecoding(){}}, shown below:

geoDecoding() {
    let geocoder = new google.maps.Geocoder();
    let theLocation = this.location;
    let latLong = this.latLong;
    self = this;

    let service = new google.maps.places.PlacesService(this.map);
    var erez_markers = [];

    return new Promise(function (resolve, reject) {
        geocoder.geocode({'address': theLocation}, function (results, status) {
            if (status === google.maps.GeocoderStatus.OK) {
                console.log(results[0].geometry.location.lat(), results[0].geometry.location.lng());
                latLong.latitude = results[0].geometry.location.lat();
                latLong.longitude = results[0].geometry.location.lng();
                this.myLatlng = new google.maps.LatLng(latLong.latitude, latLong.longitude);
                self.map.panTo(this.myLatlng);//******* this would shift map on every instantiation with new lat/lng's
            } else {
                reject(status);
            }
        });
    });
}

My state data includes default values to ensure the map displays something upon initialization:

latLong: {
    latitude: 43.6532,
    longitude: -79.3832
},
location: '',
zoom: '',

The display of the map is set globally so it can be accessed from any location. This functionality is implemented under methods:{showmap(){}}

this.map = new google.maps.Map(document.getElementById(this.theMap), {
                    center: {lat: this.latLong.latitude, lng: this.latLong.longitude},
                    zoom: this.zoom
});

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

A declaration file for the 'vuelidate' module could not be located

When I was following the installation instructions for Vuelidate in Vuejs (), I encountered a warning message at this line: import Vuelidate from 'vuelidate' The warning states: There seems to be an issue with finding a declaration file for t ...

Click on the login button once the field has reached its maximum length

I need assistance with a login form that has a maximum length of 4 characters for both empNum and ssn. Below is the code snippet: <input type="text" id="empNo" name="empNo" style="width: 90px; margin-left: 10px" maxlength="4" onkeyup="nextField(this, & ...

Updating ES6 syntax for superset in array: a step-by-step guide

I am currently working with ES6 React code that generates an array of MiniIcons on a webpage. const MiniIcons = ({miniicons}) => ( <div id="application"> {miniicons.map(miniicon => ( <MiniIcon key={miniicon.id} id={miniicon.id} ...

Obtain the index of a selected option in a Select Tag using Node.js/Express

When you make a POST request with a form in Node.js/Express For example: <select name="selectname"> <option value="value1">Value 1</option> <option value="value2" selected>Value 2</option> <option value="value3"> ...

Find a way to incorporate social media features into a web application that functions intermittently

Currently, I am in the process of developing a social media app and working on integrating a search feature to enable users to find friends. The code I have below seems to be functional at times but not consistent (quite frustrating!) The issue seems to st ...

Encountering a Jquery TypeError while trying to update the content on

I am currently working on a project where I aim to create a Java Spring application that functions as follows: upon receiving a GET request, the application sends an HTML page with a form. When the form button is clicked, a POST request containing XML cont ...

Encountering obstacles with asynchronous requests while attempting to retrieve an Excel file using ajax

I am coding JavaScript for a SharePoint project, focusing on creating a function to retrieve data from an Excel document in a library. While I have successfully implemented the basic functionality, I am facing an issue with large file sizes causing the dat ...

Modifying the id attribute dynamically using jQuery during runtime

In my project, I have a submit button with the id of "submit" that is used to save new records. // Function to add a new customer record $("#submit").click(function() { var data = $.param($("#form").serializeArray()); ...

I possess a function that can retrieve the key of an Object, but now I am faced with the task of accessing the actual Object using this value in JavaScript

This is my first time seeking advice on a technical issue. I'm currently working with the following function: export function sendRequest<T>(req: RawRequest, options) { const start = Date.now(); const reqOptions: CoreOptions = { ...

Looking to add some movement to your website? Learn how to make an image track your mouse pointer in a specific section of your webpage

I'm just starting out with web design and javascript, so please be patient. My goal is to have an image follow the mouse pointer only when it's within a specific section of my website. I've managed to make the image track the mouse cursor ...

Tips for retrieving the file name from the <input type="file" tag within a JSP page

I am looking to retrieve the file path from an HTML input type="file, which is selected by the user in the file dialog. <script> function OpenFileDialog(form) { var a = document.getElementById("inputfile").click(); SampleF ...

Angular 6 tutorial: Creating a dynamic side navigation bar with swipe and drag functionality using Angular Material/Bootstrap

I am currently working on implementing a vertical swipeable/stretchable side nav-bar with angular-material in angular 6. However, I have encountered an issue with mouse interactions for stretching the nav-bar. Below is the code snippet: Here is the HTML c ...

The submitHandler for AJAX does not function properly when using bootstrapvalidator

I'm encountering an issue with the Bootstrap validation tool found at https://github.com/nghuuphuoc/bootstrapvalidator The submitHandler function seems to be malfunctioning for me. Upon form submission, the entry is not being created and the form rel ...

HTML - Selecting Different Values in One Drop Down Based on Another Drop Down

When selecting "First Year" in the initial drop-down menu, the options "Sem1" and "Sem2" should be displayed in the second drop-down menu. Similarly, when choosing "Second Year" in the first drop-down menu, the choices "Sem3" and "Sem4" should appear in th ...

Is it feasible to establish a direct link between an Angular.js application and Dynamodb? Are there any other solutions available to eliminate the need for a backend

Personally, I believe that removing the backend could be a successful strategy for addressing sysadmin/scale issues. Do you agree with this approach? Is there a proven method for eliminating the backend in web applications that require database access? I& ...

How can I avoid C3.js legends from overlapping when hiding or showing a div?

Every time I visit a specific page, a simple chart is automatically generated: function displayOptions() { $("#div1").show(); chartRef.flush(); } function displayChoices() { $("#div1").show(); } $("#div1").hid ...

The page query functionality seems to be malfunctioning when implemented within a Gridsome component

While using <page-query> within the index works fine, I encounter an error of "edges undefined" when I try to use it inside a component. Can someone provide assistance with this issue? ...

Merge the throw new Error statement with await in a single expression

Is it possible to combine throwing an error and using the await keyword in one statement using the AND operator? The code snippet below demonstrates my intention: throw new Error() && await client.end(). So far, this approach has been working wel ...

Using AngularJS location.path for unique custom URLs

Control Code: $scope.$on('$locationChangeStart', function () { var path = $location.path(); var adminPath = '/admin/' ; if(path.match(adminPath)) { $scope.adminContainer= function() { return true; }; }); HTML <div clas ...

Having trouble triggering the button with querySelector in Angular

I have a dynamic page where I need to click on a button. I tried the code below, but it is not working and not showing any alert. However, if we use the same code in the browser console, it executes and shows an alert. Can someone please suggest how to r ...