Предотвращение TypeError: updates[0] не определено в приложении Vue.js/Django

Я разрабатываю приложение Django/Vue.js.

Сразу после формы входа Django view перенаправляет на страницу user/username, на которой файл Vue.Js загружает данные с сервера. Вот код:

async created(){
    await this.getUpdates(); 
}

Подробно о функции getUpdates() рассказано ниже; в основном, она передает в Django дату, которая необходима серверу для проведения расчетов.

    async getUpdates(){
        await fetch(baseurl + 'getupdates',
            {
                method: 'post',
                headers: {
                'Content-Type': 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
                'X-CSRFToken': await this.getCsrfToken()
                },
                body: JSON.stringify(this.date)
            }
        );
        var response = await this.loadUpdates();
        this.updates = await response.json()
    },

    async loadUpdates(){
        await this.getUser();
        var response = await fetch(baseurl + 'loadupdates',
            {
                method: 'post',
                headers: {
                'Content-Type': 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
                'X-CSRFToken': await this.getCsrfToken()
                },
                body: JSON.stringify(this.date)
            }
        );
        this.updates = await response.json() 
    }

Сниппет html, в котором используются эти обновления, представлен ниже

            <!--Avvisi-->
        <h3>Avvisi:</h3>
        <div class="container"  >
            <div class="row" v-if="updates[0].length">
                <div v-for="notice, index in updates[0]" class="col-md-3 col-6 my-1">
                <!--Qua metto le carte-->      
                    <div class="card">
                        <div class="card-body">
                            <h4 class="card-title">[[notice.titolo]]</h4>
                            <p><a v-bind:href="'notices/'+ notice.id" tabindex=0>Vedi dettaglio</a></p>
                            <button class="btn btn-primary" @click="hide(notice)" tabindex=0>Nascondi</button>  
                        </div>
                        
                    </div>
                </div>
            </div>
            <div class="row" v-else>
                Nessun nuovo avviso oggi 
            </div>
        </div>
        <br>

Проблема в том, что когда я впервые вхожу на страницу, журнал консоли показывает:

TypeError: updates[0] is undefined

Я думаю, что знаю причину, почему это происходит: когда я вхожу в систему, экземпляр Vue вызывает функцию this.getUpdates(), но, поскольку это асинхронный вызов, он отображает HTML в ожидании ответа, и поэтому update[0], в первой оценке, пуст.

Есть ли решение для этой проблемы? Спасибо.

Ваша догадка верна. Не существует способа "приостановить" выполнение внутри крючков жизненного цикла. Лучшей практикой является загрузка компонентов с состоянием загрузки, а затем срабатывание флага (или использование свойства watcher) для обновления компонентов после загрузки данных.

Простым способом решения этой проблемы было бы обернуть его внутри условного div, который проверяет, определено ли еще updates:

<div v-if="updates && updates.length>0">
    <div class="row" v-if="updates[0].length">
         <div v-for="notice, index in updates[0]" class="col-md-3 col-6 my-1">
              <!--Qua metto le carte-->      
              <div class="card">
                  <div class="card-body">
                      <h4 class="card-title">[[notice.titolo]]</h4>
                          <p><a v-bind:href="'notices/'+ notice.id" tabindex=0>Vedi dettaglio</a></p>
                          <button class="btn btn-primary" @click="hide(notice)" tabindex=0>Nascondi</button>  
                  </div>
              </div>
          </div>
      </div>
      <div class="row" v-else>
          Nessun nuovo avviso oggi 
      </div>
</div>

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

У меня нет большого опыта работы с маршрутизацией в Django и как она сочетается с Vue, но в Vue-router, и вообще говоря, если ваш компонент полностью зависит от получаемых данных, вы делаете это до принятия навигации, а затем передаете их компонентам. Для тех, кто еще использует Vue-router, вот ссылка о том, как это сделать.

Вернуться на верх