0

I am working on displaying weather data received from a weather station as a graph using charts.js. The weather data i.e. 'temperature' and 'humidity' is to be received from the weather station server as json data.

I am using XMLHttpRequest method to receive the json data from the server. But when I store the json response in a variable and use it in charts.js' Charts() method, it doesn't display anything.

I have followed few tutorials and I can't figure out a problem at least how I am using XmlHttpRequat method to receive json data from the weather station sever. Perhaps problem may be with using stored jason value in a variable and then how to use it Charts method's 'data'.

Here is my code:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">

    <title>Weather Update</title>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
    <link rel="stylesheet" href="style.css">

    <script>

    function dspChrt() {

    var requestURL = 'http://api.holfuy.com/live/?s=101&m=JSON&tu=C&su=m/s'; //URL of the JSON data
    var request = new XMLHttpRequest();  // create http request
    request.open('GET', requestURL);  // open a new request
    request.responseType = 'json';  // setting response type to JSON type
    request.send(); // send the request                       
    request.onload = function() {
    if(request.readyState == 4 && request.status == 200){
        var wData = JSON.parse(request.responseText);
        var hum = wData.humidity;

    }  }        

    var ctx = document.getElementById('myChart').getContext('2d');
    var myChart = new Chart(ctx, {
    type: 'line',
    data: {
    labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],
    datasets: [{
      label: 'Humidity',
      data: [hum], // json value received used in method
      backgroundColor: "rgba(153,255,51,0.4)"
    }, {
      label: 'Temprature',
      data: [2, 29, 5, 5, 2, 3, 10],
      backgroundColor: "rgba(255,153,0,0.4)"
    }]
  }
});
}
    </script>


  </head>


  <body onload="dspChrt();">

  <div class="container">

  <h2>Weather Update</h2>

  <div>
    <canvas id="myChart"></canvas>
  </div>

  </div>


  </body>
</html>

EDITED CODE:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">

    <title>Weather Update</title>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
    <link rel="stylesheet" href="style.css">

    <script>

    function dspChrt(hum) {

    var ctx = document.getElementById('myChart').getContext('2d');
    var myChart = new Chart(ctx, {
    type: 'line',
    data: {
    labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],
    datasets: [{
      label: 'Humidity',
      data: hum, // json value received used in method
      backgroundColor: "rgba(153,255,51,0.4)"
    }, {
      label: 'Temprature',
      data: [2, 29, 5, 5, 2, 3, 10],
      backgroundColor: "rgba(255,153,0,0.4)"
    }]
  }
});
}
    </script>

<script>

 var myVar = setInterval(loadChart, 60000); // updates chart every one minute

 function loadChart()
 {

    var wData, hum;

    var requestURL = 'https://cors.io/?http://api.holfuy.com/live/?s=759&pw=h1u5l4kka&m=JSON&tu=C&su=m/s'; //URL of the JSON data
    var request = new XMLHttpRequest({mozSystem: true}); // create http request

    request.onreadystatechange = function() {
     if(request.readyState == 4 && request.status == 200) {
        wData = JSON.parse(request.responseText);
        hum = wData.humidity;

        console.log(wData);
        console.log(hum);

        dspChrt(hum);    
  }
}


    request.open('GET', requestURL);
    request.send(); // send the request

    //dspChrt(hum);

 }

</script>


  </head>


  <body onload="loadChart();">

  <div class="container">

  <h2>Weather Update</h2>

  <div>
    <canvas id="myChart"></canvas>
  </div>

  </div>


  </body>
</html>
Nikko
  • 67
  • 1
  • 10
  • Have you tested that the JSON coming back isn't null/an expected structure? At least then you'll know if it's the data that's the problem or the graph rendering it. – James Gould Jul 23 '18 at 13:43
  • `request.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200){ var wData = JSON.parse(this.responseText); var hum = wData.humidity; } }` try like this. [https://www.w3schools.com/xml/ajax_xmlhttprequest_response.asp ]. And by the way, create the onreadystatechange function before opening and sending the request. – com Jul 23 '18 at 13:48
  • what is the object type of the humidity property of the return object? – daddygames Jul 23 '18 at 13:50
  • it's a real or float value. – Nikko Jul 23 '18 at 13:57
  • @Jay Gould: I haven't tested it but I am also thinking about it. And finding some way to test it before using. Though in some tutorials, this is the way used to get value from a json object after parsing. – Nikko Jul 23 '18 at 14:00
  • @JayGould: in console.log, it showing all the values of json object in Wdata and Humidity value in hum, though not populating graph with hum data. – Nikko Jul 24 '18 at 13:11

1 Answers1

1

Use onreadystatechange instead of onload, don't use request.responseType = 'json'; and call open() and send() after declaring the onreadystatechange.

w3schools example

var requestURL = 'http://api.holfuy.com/live/?s=101&m=JSON&tu=C&su=m/s'; //URL of the JSON data
var wData, hum;

var request = new XMLHttpRequest(); // create http request

request.onreadystatechange = function() {
  if (request.readyState == 4 && request.status == 200) {
    wData = JSON.parse(request.responseText);
    hum = wData.humidity;

    console.log(wData);
    console.log(hum);
  }
}

request.open('GET', requestURL);
request.send(); // send the request

And by the way, you create the hum variable to store the data you received inside the callback function scope, so the variable hum does not exist when you are trying to create the chart. Create the variable before the ajax request and then populate it inside the callback, that way the variable will have value when you create your chart.

com
  • 376
  • 2
  • 9
  • it raises this error on console: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://api.holfuy.com/live/?s=101&m=JSON&tu=C&su=m/s. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). – Nikko Jul 24 '18 at 11:41
  • I utilized this method from a SO post 'Alternatively, to try things out, you can prefix the URL with https://cors.io :' https://stackoverflow.com/questions/46785318/the-cors-header-access-control-allow-origin-is-missing Its removed the error but no value is shown for hum – Nikko Jul 24 '18 at 12:00
  • in console.log, it showing all the values of json object in Wdata and Humidity value in hum, though not populating graph with hum data. – Nikko Jul 24 '18 at 13:14
  • 2
    @Nikko it is not populating the graph with data because you initialize your graph **before** the data has been received. You have to put the graph initialization inside a function and call that function inside the `request.onreadystatechange` – com Jul 24 '18 at 13:26
  • I kept graph code in this function and declared another function containing request.onreadystatechange to call the graph display function. But it's raising this error: TypeError: 48.6 is not a non-null object[Learn More] Chart.min.js:12:2901 TypeError: l._view is undefined[Learn More] Where 48.6 is current hum value. I put edited code in EDITED CODE in OP. Please see this – Nikko Jul 25 '18 at 12:33
  • This worked for me! I thought you could just call `mychart.update()` but you have to make sure you setup the chart in a callback. –  Sep 09 '20 at 22:59