Error creating graph with API data - Axios / Vue

0

Hello, I'm building a graph that collects meteorological data from the city of Curitiba through an API retrieve, but nothing is collected and so the graph is not created, I'm using vue / axes for this system. >

I would like a light on this problem.

Axios code:

  var app = new Vue({
    el: "#app",
    data: {
      chart: null,
      dates: [],
      probability: [],
      precipitation: [],
      loading: false,
      errored: false
    },
    methods: {

        if (this.chart != null) {
          this.chart.destroy();
        }

        axios
          .get("http://apiadvisor.climatempo.com.br/api/v1/forecast/locale/6731/days/15?token=5ffc1cd67c7deb0d259d9388ea9db118")
        .then(response => {
          this.dates = response.data.list.map(list => {
            return data.date_br;
          });

          this.probability = response.data.list.map(list => {
            return data.rain.probability;
          });

          this.precipitation = response.data.list.map(list => {
            return data.rain.precipitation; }
          });


          /* Gera o gráfico */
      var ctx = document.getElementById("barChart");
          if (ctx) {
            ctx.height = 200;
            var myChart = new Chart(ctx, {
              type: 'bar',
              defaultFontFamily: 'Poppins',
              data: {
                labels: this.dates,
                datasets: [
                  {
                    label: "Chuva (%)",
                    fill: false,
                    data: this.probability,
                    borderColor: "rgba(0, 123, 255, 0.9)",
                    borderWidth: "0",
                    backgroundColor: "rgba(0, 123, 255, 0.5)",
                    fontFamily: "Poppins"
                  },

                  {
                    label: "Precipitação (mm)",
                    fill: false,
                    data: this.precipitation,
                    borderColor: "rgba(240,248,255)",
                    borderWidth: "0",
                    backgroundColor: "rgba(0,255,255)",
                    fontFamily: "Poppins"

                  }
                ]
              },
              options: {
                legend: {
                  position: 'top',
                  labels: {
                    fontFamily: 'Poppins'
                  }

                },
                scales: {
                  xAxes: [{
                    ticks: {
                      fontFamily: "Poppins"

                    }
                  }],
                  yAxes: [{
                    ticks: {
                      beginAtZero: true,
                      fontFamily: "Poppins"
                    }
                  }]
                }
              }
            });
        .catch(error => {
            console.log(error);
            this.errored = true;
          })
          .finally(() => (this.loading = false));
      }
    }
  });

HTML:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous">
  </head>
  <body>
    <div id="app">
        <div class="my-5">
          <div class="alert alert-info" v-show="loading">
            Loading...
          </div>
          <div v-show="chart != null">
            <canvas id="myChart"></canvas>
          </div>
        </div>
      </div>
    </div>
  </body>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

</html>

Thank you.

    
asked by anonymous 27.11.2018 / 17:25

1 answer

0

Your code should be within the VueJs mount method, so it will run the ajax run as soon as it builds the entire component. This is the code that is working, I recommend you study the vue life cycle and improve some things that are bad in this solution. Good studies!

 var app = new Vue({
el: "#app",
data: {
  chart: null,
  dates: [],
  probability: [],
  precipitation: [],
  loading: false,
  errored: false
},
mounted () {

    if (this.chart != null) {
      this.chart.destroy();
    }

    axios
      .get("http://apiadvisor.climatempo.com.br/api/v1/forecast/locale/6731/days/15?token=5ffc1cd67c7deb0d259d9388ea9db118")
    .then(response => {
      this.dates = response.data.list.map(list => {
        return data.date_br;
      });

      this.probability = response.data.list.map(list => {
        return data.rain.probability;
      });

      this.precipitation = response.data.list.map(list => {
        return data.rain.precipitation; }
      });


      /* Gera o gráfico */
  var ctx = document.getElementById("barChart");
      if (ctx) {
        ctx.height = 200;
        var myChart = new Chart(ctx, {
          type: 'bar',
          defaultFontFamily: 'Poppins',
          data: {
            labels: this.dates,
            datasets: [
              {
                label: "Chuva (%)",
                fill: false,
                data: this.probability,
                borderColor: "rgba(0, 123, 255, 0.9)",
                borderWidth: "0",
                backgroundColor: "rgba(0, 123, 255, 0.5)",
                fontFamily: "Poppins"
              },

              {
                label: "Precipitação (mm)",
                fill: false,
                data: this.precipitation,
                borderColor: "rgba(240,248,255)",
                borderWidth: "0",
                backgroundColor: "rgba(0,255,255)",
                fontFamily: "Poppins"

              }
            ]
          },
          options: {
            legend: {
              position: 'top',
              labels: {
                fontFamily: 'Poppins'
              }

            },
            scales: {
              xAxes: [{
                ticks: {
                  fontFamily: "Poppins"

                }
              }],
              yAxes: [{
                ticks: {
                  beginAtZero: true,
                  fontFamily: "Poppins"
                }
              }]
            }
          }
        });
    .catch(error => {
        console.log(error);
        this.errored = true;
      })
      .finally(() => (this.loading = false));
  }
}
 });

The code is working, I noticed that the div name was wrong and you were not picking up the canvas context, I also changed the v-show to v-if, the difference between them is that the v-show only hides the element and v-if creates or deletes it.

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B"
    crossorigin="anonymous">
</head>

<body>
  <div id="app">
    <div class="my-5">
      <div class="alert alert-info" v-if="loading">
        Loading...
      </div>
      <div v-if="!loading">
        <canvas id="myChart"></canvas>
      </div>
    </div>
  </div>
  </div>
</body>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><script>varapp=newVue({el:"#app",
    data: {
      dates: [],
      probability: [],
      precipitation: [],
      loading: false,
      errored: false
    },
    mounted() {

      axios
        .get(
          "http://apiadvisor.climatempo.com.br/api/v1/forecast/locale/6731/days/15?token=5ffc1cd67c7deb0d259d9388ea9db118"
        )
        .then(response => {
          const infograph = response.data.data
          this.dates = infograph.map(list => {
            return list.date_br;
          });

          this.probability = infograph.map(list => {
            return list.rain.probability;
          });

          this.precipitation = infograph.map(list => {
            return list.rain.precipitation;
          });


          /* Gera o gráfico */

          var ctx = document.getElementById("myChart").getContext('2d');;
          if (ctx) {
            var myChart = new Chart(ctx, {
              type: 'bar',
              defaultFontFamily: 'Poppins',
              data: {
                labels: this.dates,
                datasets: [{
                    label: "Chuva (%)",
                    fill: false,
                    data: this.probability,
                    borderColor: "rgba(0, 123, 255, 0.9)",
                    borderWidth: "0",
                    backgroundColor: "rgba(0, 123, 255, 0.5)",
                    fontFamily: "Poppins"
                  },

                  {
                    label: "Precipitação (mm)",
                    fill: false,
                    data: this.precipitation,
                    borderColor: "rgba(240,248,255)",
                    borderWidth: "0",
                    backgroundColor: "rgba(0,255,255)",
                    fontFamily: "Poppins"

                  }
                ]
              },
              options: {
                legend: {
                  position: 'top',
                  labels: {
                    fontFamily: 'Poppins'
                  }

                },
                scales: {
                  xAxes: [{
                    ticks: {
                      fontFamily: "Poppins"

                    }
                  }],
                  yAxes: [{
                    ticks: {
                      beginAtZero: true,
                      fontFamily: "Poppins"
                    }
                  }]
                }
              }
            })
          }
        })
        .catch(error => {
          console.log(error);
          this.errored = true;
        })
        .finally(() => (this.loading = false));
    }
  })
</script>

</html>
    
27.11.2018 / 18:40