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

Determining the duration since generating a unique objectid in mongodb

I am currently developing an application that offers users the option to reset their passwords. The process is quite straightforward - after entering his email address, the user will receive a link containing the new objectid number. For example: /reset- ...

What is the process for displaying images fetched from the API?

Currently, my front-end is built using React/Redux and the API side with AdonisJS. All of my images are stored within the API, and I need to find a way to display them on the front-end. Can anyone provide guidance on accomplishing this task? ...

Can a variable be assigned based on the current route being accessed?

Currently, I am using a sidenav component with the following structure: <MenuItems> <NavLink to="/contacts/new">New</NavLink> <NavLink to="/contacts/list">New (all)</NavLink> <NavLink to="/con ...

Tips for sending multiple variables in a loop as JSON data through an AJAX request

I need assistance with the code below. I am trying to pass the value[i] into a data string in a json ajax post submit. Essentially, my goal is to gather all the checked values in a form and insert them into an existing json data string using ajax. This is ...

Struggling with AJAX requests in a cordova/ratchet app for mobile devices

I encountered some challenges when trying to make an AJAX request in my cordova project. $.ajax({ url: "https://mydevserver/REST.php?method=mobileGetData", success: function(result){ alert("successful ajax"); }, error: function(xhr ...

Using Paper Checkbox to Toggle the Visibility of a Div in Polymer

Having experience with Meteor, I typically used JQuery to toggle the display of a div along with paper-checkbox: HTML: <paper-checkbox name="remoteLocation" id="remote-chk" checked>Remote Location</paper-checkbox> <div id="autoUpdate" clas ...

Issue with Angularjs: NG-repeat and filter not functioning correctly on array

After spending the last 3 hours searching on Google and Stack Overflow, I thought this would be easy, but I'm still stuck. I have a simple ng-repeat where I need to display everything from data2 that matches the unique ID in my data1's ref_id co ...

Retrieve combination values through an AJAX request using ExtJS

My UI is developed using ExtJS, and I have a specific set of tasks that need to be executed when the page loads: Initiate an ajax call to the server to fetch a HashMap. Create a combobox within the main Panel on the page. var combo = Ext.create(' ...

The setInterval function is malfunctioning

If I have the following function: function check(){ alert("Welcome"); } window.onload = check(); setInterval("check();", 5000); However, it is not working properly. Oddly enough, when I refresh the page, it works as intended. How can I resolve this i ...

What is the proper way to include a closing tag for the canvas in a Canvas rendered by Three.js

Why does three js always add canvas elements without a closing tag to the page? Is there a specific reason for this? I'm interested in adding a closing tag to this canvas element. This example page was inspected, revealing something similar to this ...

What is the process for previewing an image in Element UI?

I am currently utilizing the Element UI component el-image. I want to be able to preview an image when it is clicked using :preview-src-list, but upon first click, nothing happens. It only previews the downloaded image after clicking a second time. Is ther ...

What is the process for constructing and compiling a Vue component for utilization at runtime within Vue?

I'm currently working on a small component that I have uploaded to GitHub at: https://github.com/pksorensen/vue-library-build-issue import Vue, { VNode } from 'vue'; import * as tsx from "vue-tsx-support"; import { Component, Prop, Watch } ...

Tips for showcasing the error message from the back-end instead of the status code

After setting up a Backend server and deploying it to Heroku, I have been using the server URL to send and receive data. However, I've encountered an issue where instead of displaying the actual error message, the status code is being returned. Here ...

Can we split the PHP Photo Gallery into a second page after displaying 12 images?

I recently developed a simple PHP photo gallery for my website that pulls data from a MySQL database. By using a while loop, I am able to display three images (from ID 1 to 3) in a single row, continuing this pattern until a total of 12 images are shown. ...

How can I maintain focus selection while replacing HTML with text in a contenteditable div without losing it?

When working with a div tag that needs to be editable, the goal is to prevent users from entering any HTML into the tag. However, despite efforts to restrict input, when users copy and paste content, it often includes unwanted tags. To address this issue, ...

The problem with asynchronous requests in Ajax

In the code below, I have noticed that when an alert() box is used and then clicked, the content loads on the page. However, without the alert() box, the content does not load. I've tried researching 'Ajax' requests extensively but still can ...

What are the steps to integrate the vue-tweet-embed node package into vuejs2?

I am having trouble figuring out how to implement the vue-tweet-embed plugin in my Vue file. I keep getting an error message that says: Unknown custom element: - have you properly registered the component? If dealing with recursive components, ensure ...

Implementing Angular CDK for a dynamic drag-and-drop list featuring both parent and child elements

I'm currently working on setting up a drag and drop list within Angular using the Angular CDK library. My goal is to create a list that includes both parent and child elements, with the ability to drag and drop both parent items as well as their respe ...

Why does Angular not reset form after ng-click event?

Something seems off with my form reset after a ng-click event, am I missing something? I can successfully submit the form, but it doesn't automatically reset. Here is the error message I receive: angular.js:12701 POST 500 (Internal Server Error ...

Encountered a SyntaxError stating 'Unable to use import statement outside a module' while attempting to utilize three.js

I'm facing difficulties with incorporating three.js into my project. Initially, I executed: I am referring to the guidelines provided here: In my VS Code terminal for the project folder, I ran the following command: npm install --save three Subsequ ...