Vue.js получение значения null для json при первоначальной загрузке

#javascript #vue.js

Вопрос:

Я учусь vue.js и пытается вызвать файл json и проанализировать данные. Все работает, но когда я обновляю страницу, я вижу пустую страницу до загрузки моих данных и в журнале консоли, который я получаю TypeError: e.myData is null . Через несколько секунд данные отображаются на странице.

main.js :

 new Vue({
    el: `#app`,
    render: h => h(App,{
      props:{
        todoID: this.dataset.id
      }
    })
  })
 

и мой App.vue :

 <template>
  <div>
      <div>{{myData.getName()}}</div>
  </div>
</template>

<script>
import Info from '@/getInfo'
export default {
  name: 'App',
  props: {
    todoID: String,
  },
  data() {
    return {
      data: null,
      myData: null
    }
  },
  created() {
    fetch(`http://localhost/json-end-point/`)
      .then(async response => {
        const data = await response.json();

        if (!response.ok) {
          const error = (data amp;amp; data.message) || response.statusText;
          return Promise.reject(error);
        }

        // set the date here, am I doing this right?
        this.myData = new Info(data);
        this.data = data;
      })
      .catch(error => {
        this.errorMessage = error;
        console.error("There was an error!", error);
      });
  }
}
</script>
 

getInfo.js

 export default class Info {
    constructor(Data) {
      if (Data) {
        const data = JSON.parse(Data);
        console.log(data.name); // returns name
        // console.log(data);   // returns the json data
        this.name = data.name;
      }
    }
    
    getName() {
      return this.name;
    }
}
 

Я думаю, что делаю здесь что-то не так this.myData = new Info(data); , но я не уверен, что могу сделать.

Обновить

Я смог удалить журнал консоли, добавив v-if="myData !== null" . Все еще не уверен, что назначение подобных данных this.myData = new Info(data); -хороший подход. Как я могу улучшить этот код?

Комментарии:

1. вы можете добавить v-if в шаблон, чтобы показать его, если переменная не равна нулю. прямо сейчас страница отображается до завершения вызова

2. спасибо, что v-if="myData !== null" удалил журнал консоли. Является ли this.myData = new Info(data); это хорошим подходом? или мне следует попробовать другой способ? Я не хочу учиться не так, как надо.

3. используя новые средства, вы не можете возвращать обещание и ждать, лучшим подходом было бы обернуть выборку в асинхронную функцию

4. @KareemKamal у вас есть пример?

5. да, добавлен ответ с примером

Ответ №1:

Вот пример того, как позволить шаблону отображать разные состояния, чтобы он не пытался отобразить данные до их поступления, а вместо этого показывал индикатор загрузки.

 <template>
  <div v-if="myData">
      <div>{{ myData.getName() }}</div>
  </div>
  <div v-else-if="isLoading">
    Loading data...
  </div>
  <div v-else-if="errorMessage">
    {{ error.message }}
  </div>
</template>

<script>
import Info from '@/getInfo'
export default {
  name: 'App',
  props: {
    todoID: String,
  },
  data() {
    return {
      data: null,
      myData: null,
      error: null
    }
  },
  async created() {
    await this.getData()
  },

  methods: {
    async getData() {
      try {
        const response = await fetch(`http://localhost/json-end-point/`)

        if (!response.ok) {
          throw new Error(data?.message || response.statusText)
        }

        this.data = await response.json();
        this.myData = new Info(this.data);
      } catch (error) {
          this.error = error;
          console.error("There was an error!", error);
      }
    }
  }
}
</script>
 

Комментарии:

1. это возвращает ошибку Module build failed, reserved word 'await' для этой строки this.myData = await getData()

2. забыл this. о том , что было раньше getData , попробуй с этим

3. спасибо, все та же ошибка

4. добавлена асинхронность к созданному крючку, извините, я слишком привык к тому, что линтер делает это за меня.

5. нашел его! функция возвращает значение undefined, и мы присваиваем значение undefined myData в created (), удаление назначения исправляет это

Ответ №2:

Вы можете поместить myData.getName() вызов в вычисляемое поле, которое либо возвращает имя, myData != null либо пустую строку (или любое другое значение, которое вы хотите, когда данные недоступны).

Что-то вроде этого

 computed: {
    getName() {
        return this.myData ? this.myData.getName() : '';
    }
}