staminna
staminna

Reputation: 468

Declaring-Reactive-Properties in Vue from the documentation example

I am trying to create a simple with vue-cli and the router that fetches Covid-19 cases by Country from a JSON object of arrays. This is my first Vue app. However, I keep getting an error about "Declaring Reactive Properties". I searched dozens of similar errors on many different forums and seemed to do the trick.

Most of the code is from vue.org, except for the JSON link.

Api.js:

import axios from "axios";
import Vue from "vue";

new Vue({
  el: "#app",
  data() {
    return {
      info: null,
      loading: true,
      errored: false
    };
  },
  template: "<div>{{ output.info }}</div>",
  mounted() {
    axios
      .get("https://pomber.github.io/covid19/timeseries.json")
      .then(response => {
        this.info = response.data;
        console.log(this.info);
      })
      .catch(error => {
        console.log(error);
        this.errored = true;
      })
      .finally(() => (this.loading = false));
  }
});

export default {
  name: "About",
  props: {
    loading: String,
    errored: String,
    info: String
  }
};

About.js

<template>
<h1>Covid-19 cases by Country</h1>

<section v-if="errored">
  <p>
    We're sorry, we're not able to retrieve this information at the moment,
    please try back later
  </p>
</section>

<section v-else>
  <div v-if="loading">Loading...</div>

  <div v-else v-for="data in info" :key="data" class="currency">
    <h1>{{ data.Portugal[0].deaths }}</h1>
  </div>
</section>

Error:

[Vue warn]: Property or method "errored" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property

I can see the warning 3 times, for each of the props errored, loading and info, the most important one.

Upvotes: 1

Views: 626

Answers (1)

tao
tao

Reputation: 90068

There's a bit of confusion in what you have.

In Api.js you're mounting a Vue app without much of a template to an element with an id of app. And then you export a Vue-like object which, if imported in another component could be used like <about />. However, we don't know if you use it anywhere else.

In About.js you seem to only have a <template>, without controller or style. You probably wanted to couple the two together, which would look similar to this (I can't use SFC's on SO, so I just declared the component inline, with Vue.component()):

Vue.config.productionTip = false;
Vue.config.devtools = false;
Vue.component('About', {
  template: `<div>
    <h1>Covid-19 cases by Country</h1>
    <section v-if="errored">
      <p>
        We're sorry, we're not able to retrieve this information at the moment,
        please try back later
      </p>
    </section>

    <section v-else>
      <div v-if="loading">Loading...</div>

      <div v-else v-for="(data, name) in info" :key="name" class="currency">
        <h1>{{ name }}</h1>
        <div v-for="(entry, key) in data" :key="key">{{entry}}</div>
      </div>
    </section>
  </div>`,
  data: () => ({
    info: null,
    loading: true,
    errored: false
  }),
  mounted() {
    axios
      .get("https://pomber.github.io/covid19/timeseries.json")
      .then(response => {
        this.info = response.data;
        // console.log(this.info);
      })
      .catch(error => {
        // console.log(error);
        this.errored = true;
      })
      .finally(() => (this.loading = false));
  }
})

new Vue({
  el: '#app'
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>

<div id="app">
  <About/>
</div>


If you want to do the loading of data in parent, you have to pass the required props to <About />, along these lines:

In App.js template:

<About :loading="loading"
       :info="info"
       :errored="errored"
/>

In About.jss props:

props: {
  loading: Boolean,
  info: Object,
  errored: Boolean
}

That's the gist of it. But, in your case, that would seem an unnecessary complication.


As a side note, to speed things up towards your end goal, I took the liberty to add a few more features to your code: https://codesandbox.io/s/compassionate-dan-6z3zo
I hope you'll find them helpful.

Upvotes: 2

Related Questions