Changing a variable's value from within a Highmaps chart in Vue.js

Allow me to present my current project which involves the creation of a web application that displays data about devices spread across a country. To achieve this, I utilized Vue.js and HighCharts (employing HighMaps for the map component). The image below showcases the progress I've made so far.

https://i.sstatic.net/YHN5y.png

My next objective is to enable end-users to click on a specific region on the map and visualize all the devices within that area. For this functionality, I require the "ID" of the region, referred to as the code in HighMaps, to trigger an ajax request to my database. Furthermore, I intend to transform this new feature into a component for more flexible application usage. Below is a rough sketch illustrating my concept:

https://i.sstatic.net/QsnWH.png

Disregard the black lines in the sketch; the goal is to create a new component adjacent to the map or elsewhere in the application. Here is a snippet of my code, where both the template and script tags are embedded within the same file, following a one-page, one-component pattern. Currently, I have implemented a div with curly brackets to update a variable upon change, for debugging purposes. My primary concern lies in the plotOptions.series.point.events.click section, where referencing the this.foo variable seems to face challenges with updates. I suspect this issue might be related to scoping but require guidance on where to begin investigating.

<template>
  <div id="canvasContainer">
    <highmaps :options="chartOptions"></highmaps>
    <app-componentForDevices><app-componentForDevices>
    <div>{{foo}}</div>
  </div>
</template>

<script>
  import HighCharts from 'vue-highcharts';
  import json from '../map.json'

  export default {
    data: function () {
      return {
        foo: 'NO',
        /* Map */
        chartOptions: {
          chart: {
            map: json, // The map data is taken from the .json file imported above
          },
          plotOptions: {
            series: {
              point: {
                events: {
                  click: function () {
                    this.foo='OK'
                  }
                }
              }
            },
            map: {
              joinBy: ['hc-key', 'code'],
              allAreas: false,
              tooltip: {
                headerFormat: '',
                pointFormat: '{point.name}: <b>{series.name}</b>'
              },
            }
          },
          /* Zoom and move */
          mapNavigation: {
            enabled: true,
            buttonOptions: {
              verticalAlign: 'bottom'
            }
          },
          series: [
            {
              allAreas: true,
              showInLegend: false,
            },
            {
              borderColor: '#a0451c',
              cursor: 'pointer',
              name: 'ERROR',
              color: "red",
              data: ['it-na', 'it-mi', 'it-mo', 'it-ud'].map(function (code) {
                return {code: code};
              }),
            },
            {
              borderColor: '#a09e21',
              cursor: 'pointer',
              name: 'WARNING',
              color: "yellow",
              data: ['it-ts', 'it-av', 'it-ri'].map(function (code) {
                return {code: code};
              }),
            },
            {
              borderColor: '#4ea02a',
              cursor: 'pointer',
              name: "OK",
              color: "lightgreen",
              data: ['it-pa', 'it-ve', 'it-bo', 'it-ta', 'it-pn'].map(function (code) {
                return {code: code};
              }),
            },
          ],
        }
      }
    }
  }
</script>

<style scoped>
  svg{
    align-items: center;
  }

Your assistance in this matter is greatly appreciated. Thank you!

EDIT

Following @icecream_hobbit's suggestion, I have made progress by utilizing an ECMA6 arrow function, as it allows access to the variable stored in Vue. However, this refinement has caused me to lose access to local arguments like this.name, which was essential for displaying the selected region. Any insights or solutions to this dilemma would be valuable.

EDITv2

Thanks to @icecream_hobbit, I have successfully achieved the desired functionality. By adding an object within the parentheses, I can now utilize this for global variables and e for mouse click events.

events: {
           click: (e) => {
             this.foo = 'OK'
             this.foo = e.point.name
           }
}

Answer №1

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Prior to the introduction of arrow functions, each new function created its own specific this value (for constructors, a new object was created, for strict mode calls, it was undefined, for functions called as object methods, it was the base object, and so forth).

The this you were trying to access wasn't associated with the Vue instance. By using an arrow function like () => {/*function body*/}, you can inherit the this of the Vue instance.

An arrow function expression has a more concise syntax compared to a regular function and doesn't have its own this, arguments, super, or new.target.

UPDATE: To address the question of accessing both the Vue instance and the object instance simultaneously, you can utilize a closure.

click: function(VueInstance){
    return function() {
        VueInstance.Foo = 'OK';
    }(this)
}

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

Ending asynchronous tasks running concurrently

Currently, I am attempting to iterate through an array of objects using a foreach loop. For each object, I would like to invoke a function that makes a request to fetch a file and then unzips it with zlib, but this needs to be done one at a time due to the ...

What is the correct way to utilize the onclick() method while passing specific variables, such as an ID of a Mongoose Object Document, as arguments?

As I dynamically add rows to a front-end table based on data from a custom node.js API, each row represents a student with fields for Name, Class, Roll_No, and a button that changes color based on the student's specific value. The button code looks li ...

Is it possible to include a JavaScript script in a Laravel Blade file?

I have an Auth module from nwidart/laravel-Module. I am trying to include a script file in the Modules\Auth\Resources\views\layouts\app.blade.php file, like this: <body> ...... ... <!-- Scripts --> <script s ...

Initiating an audio call exclusively via SimpleWebRTC

I'm currently utilizing a jQuery plugin for WebRTC found here. My goal is to initiate an audio call only, but I am struggling to find a function within the plugin that allows for this. The code snippet I am using with autoRequestMedia set to false is ...

Guide to dynamically adding a class in VueJS based on a certain condition

I'm in the process of transitioning a project to Vue, and I'm curious about how I can dynamically assign classes to specific elements based on database values rendered with Vue. Previously, I had this code set up without Vue: $(document).ready(f ...

Vuejs is throwing an error claiming that a property is undefined, even though the

I have created a Vue component that displays server connection data in a simple format: <template> <div class="container"> <div class="row"> <div class="col-xs-12"> <div class="page-header"> < ...

Why is it that I cannot use the .get method on JSON data? And what is the best way to convert JSON into a map?

I'm currently in the process of creating a test for a function that accepts a map as an argument, Under normal circumstances when the code is executed outside of a test, the parameter would appear like this (when calling toString): Map { "id": "jobs ...

Handlers for adjustments not correctly updating values in introduced object

I am facing an issue with a table that displays data fetched from an API and a select dropdown. Whenever a checkbox is selected, the name key along with its value is added to an array object named selectedFields. checkbox = ({ name, isChecked }) => { ...

Upon sending an HTTP POST request from JavaScript to a Node server, the body was found to be

Trying to make an XMLHttpRequest from JavaScript to my node server. This is the request I am sending: var data = { "fname": "Fasal", "lname": "Rahman" }; var body = JSON.stringify(data); var xhttp = new XMLHttpRequest(); xhttp.open("POST", "/admin"); xhtt ...

The mySql INSERT query in my Node application is not returning any results, even after using res.json()

I have recently delved into using Node.js and I am facing a bit of a challenge. Currently, I am attempting to insert a new product into my table. However, the ID for the product is not set to auto-increment. Therefore, in order to save the ID, I am implem ...

Are the fetch functions within getStaticProps and getServerSideProps equivalent to the fetch API native to web browsers?

I've been working with Next.js for some time now and I'm questioning the fetch API used in both getStaticProps and getServerSideProps. Below is my understanding of these functions: getStaticProps runs during build time and ISR getServerSidePro ...

What are some other options besides object-fit?

Currently seeking a replacement for the css object-fit property that functions properly in Firefox and IE. While it works well in Chrome and Opera, it is not compatible with Firefox and IE. Experimented with the imgLiquid Plugin, but encountered issues w ...

Updating a React JS State using a Parameter

Is it feasible to develop a function that accepts a parameter (either a string of the state name or the actual state) and then assigns the state related to the parameter? SetState(x) { // Suppose x can be any state we have already defined (it sh ...

HTML: Mark the chosen hyperlink or tag

In my HTML page, I am looking to keep the link selected when it is clicked on. Here is the initial HTML code: <table class="main-dev"> <tr> <td> <a class='titleForm' style="cursor:pointer"> ...

Error: Failed to cast value "{ email: 'example@email.com' }" to ObjectId (type Object) for the "_id" path in the "User" model

How can I use the Mongoose ID to fetch data and send it to the client's browser? My Mongoose Database Data: {"_id":{"$oid":"6404fc0b9e6a0640b0deb716"},"username":"dddd","email":"[email&# ...

What is the best way to obtain the accurate innerHeight of a div on the initial attempt

Within my webpage, there is a hidden sub navigation with its height initially set to 0. This sub navigation contains various sections of sub navs. When a section is clicked, I obtain the name of that section and then retrieve the innerHeight of the corres ...

Updating a Vue ref does not result in the component reflecting the changes made

My Vue3 form has three text inputs and a group of checkboxes. To implement this, I am using the bootstrap-vue form along with its checkbox-group component. After calling an API to fetch default values for the form, I update the ref as shown below. Interes ...

Show a modal component from another component in Angular 2

As a newcomer to Angular, I'm working on a modal component that changes from hiding to showing when a button with (click) is clicked. The goal is to integrate this modal into my main component, allowing me to display the modal on top of the main conte ...

Calculate the pixel distance between various divs by measuring the horizontal distance from the left border to the right

I am trying to find the precise distance between : #main div left edge to the first div with class="b" between the first div with class="b" to the second div with class="b" It's worth noting that the divs may be arranged randomly and could have fix ...

Utilizing Codeigniter for transmitting JSON data to a script file

When querying the database in my model, I use the following function: function graphRate($userid, $courseid){ $query = $this->db->get('tblGraph'); return $query->result(); } The data retrieved by my model is then encoded in ...