When the component is initialized, the computed property is not being evaluated

My maps component initializes a Google map, adds markers based on props passed from the parent, and sets the correct bounds of the map. However, the markers are added through a computed property to make it reactive. Everything seems to be working fine, except that the addMarkers function within my computed properties does not evaluate when the page and component are loaded.

The strange thing is that when I open Vue Devtools and click on the maps component, addMarkers immediately evaluates and updates the map correctly.

Any assistance would be greatly appreciated :-)

<template lang="pug" >

div.google-map(id="results-map")

</template>
<script>

import Gmaps from 'gmaps';

export default {
    name: 'maps',
    props: {
        results: {
            type: Array,
            required: true
        }
    },
    data() {
        return {
            map: {},
            bounds: {}
        }
    },
    computed: {
        addMarkers() {
            this.results.forEach((result) => {
                if (result.latitude && result.longitude) {
                    var marker = this.map.addMarker({
                        lat: result.latitude,
                        lng: result.longitude,
                        title: result.name,
                        infoWindow: {
                            content: result.name
                        }
                    });
                }
                this.bounds.extend(marker.position)
            });
            this.map.fitBounds(this.bounds)
        }
    },
    mounted() {
        this.map = new Gmaps({
            div: '#results-map',
            lat: 0,
            lng: 0,
            zoom: 15
        });
        this.bounds = new google.maps.LatLngBounds();
    }
}
</script>

Answer №1

A computed property is designed to return a specific value, whereas your addMarkers function does not return any value.

In addition, a computed property is only calculated when it is requested. Therefore, if the markers are not displayed when the component is created, it is likely because the computed property is never requested.

However, when you inspect the developer tools, VueJS attempts to evaluate the computed property and runs the code. As a result, your code adds the markers, even though it is not within a computed property.

There are several ways to address this issue:

Option 1: Force the evaluation of the computed property on the mounted hook:

mounted() {
    this.map = new Gmaps({
        div: '#results-map',
        lat: 0,
        lng: 0,
        zoom: 15
    });
    this.bounds = new google.maps.LatLngBounds();
    this.addMarkers()
}

Option 2: Turn your addMarkers function into a method that can be executed whenever necessary:

import Gmaps from 'gmaps';

export default {
    name: 'maps',
    props: {
        results: {
            type: Array,
            required: true
        }
    },
    data() {
        return {
            map: {},
            bounds: {}
        }
    },
    methods: {
        addMarkers() {
            this.results.forEach((result) => {
                if (result.latitude && result.longitude) {
                    var marker = this.map.addMarker({
                        lat: result.latitude,
                        lng: result.longitude,
                        title: result.name,
                        infoWindow: {
                            content: result.name
                        }
                    });
                }
                this.bounds.extend(marker.position)
            });
            this.map.fitBounds(this.bounds)
        }
    },
    mounted() {
        this.map = new Gmaps({
            div: '#results-map',
            lat: 0,
            lng: 0,
            zoom: 15
        });
        this.bounds = new google.maps.LatLngBounds();
        this.addMarkers()
    }
}

For instance, if you want the markers to update when the results prop changes, you can utilize the watch property:

export default {
    ...
    watch: {
        results: {
            deep: true,
            handler () {
                this.addMarkers()
            }
        }
    }
}

Answer №2

The addMarkers computed property doesn't seem to be utilized in your code. Perhaps you could consider converting it into a method and invoking it within the mounted function for better functionality.

Answer №3

To tackle changes in the results occurring externally to your component:

  • Convert the addMarkers() computed property into a watcher for the results.

This ensures that the code is triggered every time the results prop alters.

Furthermore, considering you are implementing some DOM manipulation logic within your mounted() hook:

  • Encase the logic of the results watcher inside a Vue.nextTick() to guarantee its execution only after the DOM is ready for modification (i.e., once you've set up <google-maps>):

Vue.nextTick(): Postpone the callback's execution until after the subsequent DOM update cycle. Use it right after modifying some data to await the DOM update.

Hence, your updated watch block (formerly the addMarkers() computed property) will be as follows:

watch: {                                                                 // line changed
    results: {                                                           // line changed
        deep: true,                                                      // line changed
        handler () {                                                     // line changed
            Vue.nextTick(() => {                                         // line changed
                this.results.forEach((result) => {
                    if (result.latitude && result.longitude) {
                        var marker = this.map.addMarker({
                            lat: result.latitude,
                            lng: result.longitude,
                            title: result.name,
                            infoWindow: {
                                content: result.name
                            }
                        });
                    }
                    this.bounds.extend(marker.position)
                });
                this.map.fitBounds(this.bounds)
            });                                                         // line changed
        }                                                               // line changed
    }
},

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

Make sure to incorporate certain node_modules folders within Babel 7

My issue involves a dependency located in the node_modules directory that requires compilation through Babel. Despite upgrading my stack, I am unable to get Babel to compile the dependency. Current versions: @babel/core 7.5.4 webpack 2.7.0 Here is my w ...

An effective way to mimic an un-exported (private) function within a user module using Jest

In my code, I have a function that handles API requests called "private" and several other functions that initiate specific requests with configuration objects. For example, in the requestUploadStatementFile file. I want to test these public functions, bu ...

Having trouble sending form data using the jQuery AJAX POST method?

I am facing an issue with a simple form that is supposed to send data to PHP via AJAX. However, when I submit the form, the data does not get sent across. Here is the JavaScript code: $(document).ready(function(e) { $('#update').submit(func ...

Showing undefined or null values in React and JavaScript

My goal is to format undefined or null values by italicizing them. If the value is an empty string, it should be displayed as is. If it has a value, that value should also be displayed as is. However, I am encountering an issue where null or undefined val ...

When the file is active on a local machine, the bot commands run smoothly. However, these commands do not execute on a remote

Lately, while working on coding a discord bot using discord.js, I came across an issue. Whenever I run my bot on my local machine, all the commands work perfectly fine. However, after committing and pushing the code to GitHub, and then allowing buddy.works ...

react-native-track-player failing to play song requested from Express server

I set up an expressjs server with a 'songs' route that serves .mp3 files. Here is the code for the Songs Route: import express from "express" const path = require("path") const router = express.Router() ... router.get(" ...

This error message appears in vue.js: "TypeError: Trying to read an undefined property 'then'."

I am currently working on implementing email verification in my vue.js/express application. I have successfully created the user and sent emails. However, displaying a message like "verification mail sent" is not functioning as expected. The issue arises ...

The Facebook SDK's function appears to be triggering twice

I am currently in the process of integrating a Facebook login button into my website and have made progress, but I have encountered a problem. The Facebook SDK JavaScript code that I am using is as follows: function statusChangeCallback(response) { ...

What is the best way to display my table?

In the index.php view, you will find my table located <table class="striped"> <thead> <tr> <th>Id</th> <th>Name</th> <th ...

Storing div content in database directly

I have a straightforward div that allows users to edit content on the page. I need to save this content in a database, but without including any HTML tags while still preserving line breaks. Currently, I am using the innerText property for this purpose. N ...

The URL routing in Vue-router seems to be incorrect as it directs to the wrong page. To fix this issue, make sure to include a '#' before the

Welcome to my website! Check out my home page here: https://i.sstatic.net/znfq0.jpg If you're interested in reading my blog, visit the blog page here: https://i.sstatic.net/oiYSY.png I've built this site using vue3. Here's a snippet of th ...

Getting started with Preact.js: Setting up an auto re-run server similar to React.js

Is there a way to set up a development server for Preact similar to how React operates with npm start? Currently, when I use the same command with Preact, it launches a static server and requires manual restart each time I make changes to my project. Here ...

Having trouble sending a POST request with body parameters in Node.js? The error "undefined req.body.param" might be popping up when you're

I've encountered an issue with my server.js code: const bodyParser = require('body-parser'); const cors = require('cors'); const morgan = require('morgan'); var express = require('express') , http = requir ...

Integrate predictive text suggestions in JavaServer Pages for efficient form filling

After some research, I have managed to solve the issue I was facing. On my jsp page, I have three text boxes. When I enter data into the first text box, it triggers a call to get.jsp to fetch data from the database and populate the second text box. However ...

Encountering problems with ajax technology

As a newcomer to Laravel and Ajax, I am facing an issue with displaying the state of the selected country in a dropdown list. Although the data is successfully fetched from Laravel and received through Ajax, I am struggling to dynamically add it to the H ...

How can I transfer a particular data value from a div to JavaScript within Laravel 5.0?

Displaying separate square divs based on integers retrieved from the database. This is the front-end view. I want to pass the room ID (code) to a JavaScript function when clicking on these div elements. https://i.stack.imgur.com/aIYTr.png Below is my cur ...

What steps are involved in a server utilizing Next.js to create a complete document for transmission to the client?

Understanding Next.js has been quite challenging for me. I am struggling to grasp how it operates on the server and how the server is able to implement server side rendering with the files generated by Next.js during the build process. I have a good under ...

Add items to a fresh record using Mongoose and Express

In my model, I have an array of objects that I want to populate with new items when creating a NEW document. While I have found information on how to achieve this using findAndUpdate, I am struggling to figure out how to do it with the save() method. This ...

Vue - Implementing plugin as a prototype functionality

For notifications in my application, I've incorporated the euvl/vue-notification library. Each time I need to notify the user, I have to include the following code: If I'm within a Vue component: this.$notify({ group: 'panel', ...

What is the best way to determine the quantity of elements received from an ajax request?

Here's the method I am currently using to count the number of li elements returned from an AJAX call: $.post('@Url.Action("actionName", "controller")', function (data) { $('#notificationCounter').html($(data).find('li&a ...