Using Plotly.js within a deleted Vue.js component may result in displaying an incorrect chart

Issue

I am facing a problem with deleting one of the components that contains a chart. Even after deleting the component, the chart remains visible.

To see an example, check out this jsfiddle: https://jsfiddle.net/m4ywp5fc/4/

Solution Attempted

I attempted to replot the chart using Plotly.replot, but it seems like Vue.js might be interfering with this process internally. Additionally, applying Plotly.purge did not resolve the issue in this case.

Code Snippet

For code reference, please visit jsfiddle: https://jsfiddle.net/m4ywp5fc/4/

JavaScript Code

Vue.component('chart-one', {
    props: ['id'],

  template: `<div :id="'chart-' + id"></div>`,

  mounted () {
    const trace = {
      x: [1, 2, 3, 4],
      y: Array.from({length: 4}, () => Math.floor(Math.random() * 40))
    }

    Plotly.newPlot('chart-' + this.id, [trace])
  }
})

new Vue({
  el: '#app',

  data: () => ({
    charts: [1, 2]
  }),

  methods: {
    remove () {
        this.charts.splice(0, 1)
    }
  }
})

HTML Code

<script src="https://unpkg.com/vue"></script>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

<div id="app">
  Charts: {{ charts }}
  <button @click="remove">
    Delete first chart
  </button>

  <div v-for="(chart, index) in charts">
    <chart-one :id="'chart-' + index"></chart-one>
  </div>
</div>

Note

Please note that the actual application is more complex than this isolated scenario.

Answer №1

Your issue stems from two main factors:

An error in your sample code

<chart-one :id="'chart-' + index"></chart-one>

should actually be:

<chart-one :id="'chart-' + chart"></chart-one>

Inability to handle changes in component properties

In Vue, components are expected to update automatically when their properties change. However, your component fails to address this scenario.

Here's what's happening:

  1. Vue initially renders 2 instances of chart-one with values [1, 2]
  2. When the button is clicked, Vue is requested to rerender with just 1 chart-one [1]
  3. Vue updates the id variable on the first component to 2 and realizes there is still 1 unused component, so it removes it

This can be remedied in the following manners:

Using a key attribute:

By assigning a key to the chart-one component, Vue is able to track the instances effectively:

<chart-one :id="'chart-' + chart" :key="chart"></chart-one>

Instead of simply updating values in the first component, Vue intelligently recreates DOM nodes to match the passed values.

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

How to save HTML content in a variable for future use in Next.js

When working with Next JS, my code resembles something like this: function Test() { return ( <section> <div>Test</div> </section> ); } Now, imagine that I want to have multiple entries here, gen ...

Leveraging Handlebars for templating in Node.js to incorporate a customized layout

app.js const exphbs = require('express-handlebars'); app.engine('handlebars', exphbs({defaultLayout: 'layout'})); app.set('view engine', 'handlebars'); app.use('/catalog', require('./routes/ ...

The issue of undefined database columns arises when attempting to transmit data from an HTML form to a MySQL database via Express

My primary objective is to develop a RestAPI using Node.js and test it in a small HTML application. With the guidance of my instructor, I successfully created the RestAPI based on an example and customized it to work with my own MySQL database. Testing ea ...

PHP/AJAX user action history manager

Is there a library available that offers undo/redo functionality with a complete history for a web application? One possible solution could be a system using php/javascript/ajax where you can record the opposite action and variable state for each user acti ...

Feed information into a Select element from the Material UI version 1 beta

Having trouble populating data from a < Select > component in Material UI version 1.0.0.0 beta. Snippet of my code: This section is located inside the render() method. <Select value={this.state.DivisionState} onChange={this.handleChangeDi ...

Tips for regularly retrieving information from a psql table

I have a scenario where I am retrieving data from a psql table and converting it into a JSON array to be used for displaying a time series chart using JavaScript. The data that is passed needs to be in the form of an array. Since the data in the table get ...

What is the best way to integrate JavaScript with my HTML command box?

I'm having some trouble with an HTML command box that is supposed to execute commands like changing stylesheets and other tasks. I thought I had everything set up correctly, but it doesn't seem to be working at all. Below is the HTML code with th ...

Tips for enabling a keypad to restrict input field character limit

Encountering an issue with an input field that has a maximum length of 6 characters. Typing normally seems to work fine, but when using a custom keypad, the limit is not enforced and it allows for more than 6 characters to be entered. HTML: <div cl ...

In JavaScript, how is the symbol "." referred to as?

While I am familiar with its purpose and the language terminology, could you please provide the official name for the period/dot used in Javascript/jQuery? Appreciate your help! ...

Executing a cloud function in Firebase from an Angular-Ionic application by making an HTTP request

I am a newcomer to GCP and app development, so please bear with me if this question seems mundane. Currently, I have an angular-ionic app that is connected to Firebase allowing me to interact with the Firestore database. Now, my challenge is to invoke a ht ...

Why isn't my classList .add method working properly?

I've created a video slider background on my website, but I'm having trouble with the Javacript for video slider navigation. When I click on the button to change the video, nothing happens. The console is showing an error message that says "Canno ...

Paste a data point from an Excel spreadsheet into a JavaScript script

I'm encountering a major challenge. Currently, I am creating a login process for a client and here is the approach I have taken: function Jump(pal){ if (pal=='10528'){window.open('http://www.google.es','_parent')} Subs ...

Adding and removing controls on Google Maps in real-time

Recently, I encountered an issue with my custom search bar overlapping some controls on my map. Despite adjusting the z-index of these controls, they continued to stay on top. To work around this problem, I thought about hiding the controls during the sear ...

Steps for installing a package using npm without the need for configuring a package.json file

According to this source, it is feasible to install npm packages before creating the package.json file. After installing nodeJS on my computer, I attempted to run the following command in an empty directory: npm install jQuery This resulted in the follow ...

Issue with redirect using Node.js promise

I’ve created a settings page where users can add and remove filters. To handle the deletion process, I’ve implemented this jQuery function: $('#delete-filter').click(function (e) { var filtername = $('#filter-list').val(); ...

Is there a way to retrieve the HTML code of a DOM element created through JavaScript?

I am currently using java script to generate an svg object within my html document. The code looks something like this: mySvg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); myPath = document.createElementNS("http://www.w3.org/2000/svg", ...

Change the hover effects on the desktop to be more mobile-friendly

In my desktop version, I have implemented some code that enables hovering over a button to display additional information or text. How can I modify this for mobile so that nothing happens when the button is tapped on? .credit:hover .credit-text, .credit- ...

Using asynchronous data in Angular 2 animations

Currently, I have developed a component that fetches a dataset of skills from my database. Each skill in the dataset contains a title and a percentage value. My objective is to set the initial width value of each div to 0% and then dynamically adjust it t ...

"Shopping just got easier with our new drag and drop feature! Simply drag items

I want to develop a Virtual Shopping Cart system. Items will be retrieved from a database. A virtual basket will be available. Users can drag items and drop them into the basket, similar to shopping in a mall. Once the user clicks the save button, the s ...

Arrays data being retrieved and set by Chrome Extension are visible in the console but not appearing in the HTML

Having trouble displaying my arrays in HTML. I'm attempting to do this within a Chrome Extension. While I can view the array perfectly in console.log, I'm encountering issues when trying to add it to the HTML DOM: /* Generating the array f ...