[Chartjs]-After form submit, function runs quickly and chart.js shows up for a second then goes away

3👍

event.preventDefault() was missing at form submit:

The reason why your chart does not appear is because the event.preventDefault() statement was missing in your form-submit. Hence, your form was sending an HTTP request (the default action) instead of executing your code.

I edited your code:

  1. added event.preventDefault() at form submit
  2. declared variables outside functions in order to avoid re-declaring repeatedly
  3. eliminated the async functionality, as fetch() is a Promise (works like an async callback already, waiting for response from server)
  4. re-aranged order:
    first call dataToGraph() at form submit (with fetch() for getting the data)
    then, when fetch()-API returned the data (async), call graphit()
  5. re-assign the data to your chart (x- and y-axis data) and top label and then update() the chart
  6. adapted code for final version of chart.js v3.5.1 for improved performance (v3.x not compatible with v2.x):
  7. Load initial data for Italy with dataToGraph()

Run code snippet and enter a country (‘Italy’, ‘Germany’, ….)
(case-sensitive: first letter has to be capital letter)

// define all variables here outside functions
// in order to avoid re-assigning multiple times
let xs = [];
let ys = [];
let dataset = {};

dataset.xs = xs;
dataset.ys = ys;

let country = "Italy";

let today = new Date();
let dd = String(today.getDate()).padStart(2, '0');
let mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
let yyyy = today.getFullYear();
today = yyyy + '-' + mm + '-' + dd;

const delayInMilliseconds = 100000;

const ctx = document.getElementById('myChart').getContext('2d');

const myChart = new Chart(ctx, {
    type: 'line',
    data: {
        labels: dataset.xs,
        datasets: [{
            label: `Covid 19 Confirmed cases in ${country}`,
            data: dataset.ys,
            backgroundColor: ['rgba(255, 99, 132, 0.2)'],
            borderColor: ['rgba(255, 99, 132, 1)'],
            borderWidth: 1,
            fill: false,
        }]
    },
    options: {
        responsive: true,
        maintainAspectRatio: false,
        scales: {
            yAxes: { // <-- axis is not array '[{' anymore, now object '{'
                scaleLabel: {
                    display: true,
                    labelString: 'Confirmed Cases'
                }
            },
            xAxes: { // <-- axis is not array '[{' anymore, now object '{'
                scaleLabel: {
                    display: true,
                    labelString: 'Date'
                }
            }
        }
    }
});

// Load initial data for Italy
document.getElementById('country').value = country;
dataToGraph();

// here goes your Event-Listener with function as argument;
document.getElementById('country_form').addEventListener('submit', dataToGraph);

function dataToGraph(event) {
  if (event) event.preventDefault(); // <-- this was missing
  
  country = document.getElementById('country').value;
  // console.log("test 1", country);
  
  // give feedback to user that data is loading in background
  myChart.data.datasets[0].label =  `loading ... ${country}`;
  myChart.update();

  // set all variables to empty again:
  xs = [];
  ys = [];
  dataset = {};
  dataset.xs = xs;
  dataset.ys = ys;

  // fetch() is a Promise, i.e. it is like an async callback already,
  // hence no need to call async again.
  fetch(`https://webhooks.mongodb-stitch.com/api/client/v2.0/app/covid-19-qppza/service/REST-API/incoming_webhook/countries_summary?country=${country}&min_date=2020-04-22&max_date=${today}`)
    .then(response => response.json())
    .then(days => {
        days.forEach(day => {
            ys.push(day.confirmed);
            xs.push(day.date);
        });
        dataset.xs = xs;
        dataset.ys = ys;
        // console.log("xs", xs);
        // console.log("ys", ys);
        // console.log(`https://webhooks.mongodb-stitch.com/api/client/v2.0/app/covid-19-qppza/service/REST-API/incoming_webhook/countries_summary?country=${country}&min_date=2020-04-22&max_date=${today}`);
        // console.log(dataset);
        
        // now you can graph it
        graphit();
    })
    //return { xs, ys };
};


function graphit() {
    document.getElementById('myChart').style.display = "block";
    // const dataset = dataToGraph();

    // console.log("dataset.xs", dataset.xs);
    // console.log("dataset.ys", dataset.ys);

    // re-assign the datasets again (x- and y-axis)
    myChart.data.labels = dataset.xs;
    myChart.data.datasets[0].data = dataset.ys;
    myChart.data.datasets[0].label =  `Covid 19 Confirmed cases in ${country}`;
    // now update your chart
    myChart.update();
};
<!-- <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"></script> -->

  <!-- get the latest version of Chart.js, now at v3.5.1 -->
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

  <div id="banner">
    <div id="banner_details">
      <h2>CoData</h2>
    </div>
  </div>

 <div id="one_line">
   <div id="main_title">
     <h1>Covid-19 Data</h1>
   </div>

   <div id="user_query_data">
     <form id="country_form">
       <input type="text" placeholder="Country" id="country">
       <input type="submit" value="Search">
     </form>
   </div>
 </div>

 <div id="confirmed_graph">
   <canvas id="myChart" height="500" width="300"></canvas>
 </div>

Final Note:
You might consider to add the x: { type: 'time' ... functionality to your chart, which would present the x-asis labels (dates) better. See my answer chart.js time series for more details.

By the way: nice API – I like it 👍

and welcome to stackoverflow

Leave a comment