Estoy aprendiendo vue.js y tratando de llamar a un archivo json y analizar los datos. Todo funciona, pero cuando actualizo la página, veo una página en blanco antes de que se carguen mis datos y en el registro de la consola TypeError: e.myData is null . Después de unos segundos, los datos se muestran en la página.
main.js :
new Vue({ el: `#app`, render: h => h(App,{ props:{ todoID: this.dataset.id } }) }) y mi 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 && 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; } } Creo que estoy haciendo algo mal aquí this.myData = new Info(data); pero no estoy seguro de lo que puedo hacer.
Pude eliminar el registro de la consola agregando v-if="myData !== null" . Todavía no estoy seguro de asignar datos como este this.myData = new Info(data); es un buen enfoque. ¿Cómo puedo mejorar este código?
Este es un ejemplo de cómo permitir que la plantilla muestre diferentes estados para que no intente procesar los datos antes de que lleguen, sino que muestre un indicador de carga en su lugar.
<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>Puede colocar la llamada myData.getName() dentro de un campo calculado que devuelve el nombre si myData != null o una cadena vacía (o cualquier valor que desee cuando no hay datos disponibles).
Algo como esto
computed: { getName() { return this.myData ? this.myData.getName() : ''; } }