Vue Charts.js failing to render charts post data retrieval

Here is an example of a JSON response: [[61,57,34],[1,1,3]]. I would like to use the first array for labels and the second array for data.

If I manually set labels and data inside the app, it works fine.

For example: labels: ["q", "w", "e"] data: [1, 5, 10]

Vue.component('chart', {
  props: ['labels', 'data', 'type'],
  template: `
    <canvas style="width: 512px; height: 256px"></canvas>
  `,
  mounted: function () {
    new Chart(this.$el, {
      type: this.type,
      data: {
          labels: this.labels,
          datasets: [{
              label: '# of Votes',
              data: this.data,
              borderWidth: 1
          }]
      },
      options: {
          scales: {
              yAxes: [{
                  ticks: {
                      beginAtZero:true
                  }
              }]
          }
        }
      })
  }
});

new Vue({
  el: '#app',
  data: {
    message: "test",
    labels: [],
    data: []
  },
  methods: {
    fetchData: function() {
      this.$http.get('/admin/fetch_data').then(res => {
        this.labels = res.body[0];
        this.data = res.body[1];
      })
    }
  },
  beforeMount() {
    this.fetchData()
  }
});

Component on the page:

<div id="app">
  {{message}}
  <chart :labels="labels" :data="data" type="bar"></chart>
</div>

The data seems to be loaded, but there are no chart bars displayed on the page.

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

Answer №1

Your data may not be fetched yet because you are using an async task to retrieve it. As a result, when the component's mounted hook is called, the props are empty since the data has not finished loading.

To resolve this issue, follow these steps:

Vue.component('chart', {
  props: ['labels', 'data', 'type' 'loaded'],
  template: `
    <canvas style="width: 512px; height: 256px"></canvas>
  `,
  watch:{
      loaded(isLoaded){
          if(isLoaded){
              this.drawChart();
          }
      }
  },
  methods:{
      drawChart: function () {
        new Chart(this.$el, {
          type: this.type,
          data: {
              labels: this.labels,
              datasets: [{
                  label: '# of Votes',
                  data: this.data,
                  borderWidth: 1
              }]
          },
          options: {
              scales: {
                  yAxes: [{
                      ticks: {
                          beginAtZero:true
                      }
                  }]
              }
            }
          }) 
    }
  }
});


new Vue({
  el: '#app',
  data: {
    message: "test",
    labels: [],
    data: [],
    loaded: false
  },
  methods: {
    fetchData: function() {
      this.$http.get('/admin/fetch_data').then(res => {
        this.labels = res.body[0];
        this.data = res.body[1];
        this.loaded = true;
      })
    }
  },
  created() {
    this.fetchData()
  }
});

html

<div id="app">
  {{message}}
  <chart :labels="labels" :data="data" :loaded="loaded" type="bar"></chart>
</div> 
  • Add a property loaded set to false in your root Vue instance and pass it as a prop

  • Change the loaded to true in the success callback of the promise returned by your this.$http.get() request

  • Set up a watcher in your chart component monitoring the loaded prop

  • Call the drawChart method when the loaded prop changes to true

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

Comparing the benefits of using ajax to switch pages versus the traditional method of loading pages

Is it advisable to intercept all internal links and load the target page using ajax? The new history API in HTML5 allows for changing the URL in the address bar as well. Are there any drawbacks to this approach compared to the old traditional way of lett ...

Creating PDFs with Vue.js from HTML sources

Looking for a way to generate PDFs and insert variable values in specific locations for an order confirmation on my website. Planning to store the generated PDFs on Firebase Storage. Any suggestions on libraries or methods to achieve this? Is it possible ...

Reinitializing the database with Cypress (postgresql)

When populating the database, I intentionally do it partially for certain tests. However, after completing all tests, I would like to reset the database in order to avoid any complications that may arise during the next populate process. How can I efficien ...

Creating fixed-size arrays within a Mongoose schema is a commonly sought after feature that allows

For a specific scenario where I have example input: [[1,2],[3,2],[1,3],...,[4,5]] I am wondering about the correct way to define a model schema in mongoose. Here is my initial Schema: const SubproductSchema = new Schema({ ... positions: [{ type: ...

The functionality of Node.js middleware is not functioning correctly

My module contains Routes, and I want to verify access before allowing users to proceed. Within the Routes module, there are two routes and two access-check functions that I want to use as middlewares: const checkUser = (req, res, next) => { if (!us ...

Updates made to the stylesheet in Tailwindcss do not immediately appear in the browser

After adding a class, I find myself having to stop the Nuxt server, reload VS Code, and then run "npm run dev" in order to see the changes take effect. Below is my tailwind.config.js : /** @type {import('tailwindcss').Config} */ module.expo ...

The tab indicator in Material-UI fails to update when the back button is clicked

My code is currently functioning well: The tab indicator moves according to the URL of my tab. However, there is a peculiar issue that arises when the back button of the browser is pressed - the URL changes but the indicator remains on the same tab as befo ...

Remove search results in real-time

I'm currently working on implementing a search feature for a web application. While I have made some progress, I am facing an issue with removing items when the user backspaces so that the displayed items match the current search query or if the searc ...

Accessing each element within a Next.js application through a personalized hook during page load

Within my Next.js application, I have implemented a React hook that retrieves the currently authenticated user and stores it in global state. I am looking to execute this hook once on page load while making it accessible to every component within the app. ...

Utilize vuex v-model to define the value of an object component

Coordinating input elements with object keys in Vuex state is my current challenge. Imagine I have this object: myObj: { foo: 1, bar: 2 } Within a component, I have a computed property set up like so: myObjVals: { get(){ return this.$store.state.myObj ...

Paper.js: Is there a way to prevent canvas height and width from changing when the window is resized?

My canvas with paperjs is set up to resize dynamically when the window is resized. I appreciate any help in advance. HTML <canvas id="myCanvas" height="800" width="1000"></canvas> JS var Initialize = function () { var canvas = document ...

Learn the Method Used by Digg to Eliminate "&x=0&y=0" from their Search Results URL

Instead of using a regular submit button, I have implemented an image as the submit button for my search form: <input id="search" type="image" alt="Search" src="/images/searchButton.png" name="" /> However, I encountered an issue in Chrome and Fire ...

.bootstrapMaterialDatePicker does not work within Codeigniter version 3

I am experiencing an issue with my form that has two date fields stored as varchar <div class="row clearfix"> <div class="col-lg-2 col-md-2 col-sm-4 col-xs-5 form-control-label"> <label for="ar ...

The completion event was not triggered during the AJAX request

I am having an issue with a function that I have created to make an ajax call. Despite using the .done method, it does not seem to be firing as expected. Upon checking my console for errors, I came across the following message: https://i.sstatic.net/CbYBR ...

When I try to insert new data into a MongoDB collection during an update operation, the existing data is being overwritten instead

While updating data, I have a requirement to also add new data. Specifically, I need to append data to an existing object in a for loop that stores data in a database. However, when attempting this, the data is being updated instead of added to the current ...

Insert a parameter or substitute the existing value if detected

Trying to create a JavaScript regex that searches for a parameter in a URL and replaces its value if found. If the parameter is not found, it should be added to the URL. Here are a couple of scenarios: http://www.domain.com/?paramZ=123456 https://www.dom ...

Breaking apart a pipe-separated text and sending it through a JavaScript function

CSS: <div class="pageEdit" value="Update|1234567|CLOTHES=5678~-9876543?|5678"> <a href="https://host:controller">Update</a> </div> Trying to retrieve the data within the div and pass it into a JavaScr ...

Setting the height to 100% on the body and html tags can lead to scrolling problems

After implementing the CSS code below, I have encountered some unexpected behavior: body, html{height:100%; overflow-x:hidden} Despite vertical scrollbars appearing as intended when the page exceeds screen height, detecting the scroll event on the body e ...

Issue encountered while retrieving JWT

Currently, I am tackling the challenge of implementing JWT authentication using Angular and Java Jersey. I have successfully managed to send the JWT token from the server to the client, which can be observed as a POST response with a status code of 200 in ...

What is the source of this error message "Exceeding maximum characters in string literal"?

Hey everyone! Sorry for the bother, but I'm a bit stumped on this issue. Within my view, I have the following code snippet: <fieldset> <dl> <dt> <label for="FormTypes">Form Type:</label> ...