Компонент Vue JS не реагирует при получении данных с использованием fetch

1

У меня странная проблема в приложении Vue. Компонент выглядит следующим образом:

...
<template v-for="foo in foos">
   <Elm v-if="foo.visible" :key="foo.label" :bar="foo" />
</template>
...

"Elm" - это значение в объекте, полученном из файла JSON. Компонент реагирует, если я получаю файл JSON локально:

<script>
    import datas from "datafile.json";
    ...
    methods: {
        fillFoos() {
            datas.forEach(data => {
               this.foos.push(data)
            })
        }
    },
    mounted: {
        this.fillFoos()
   }
   ...
</script>

Но когда я извлекаю файл удаленно с помощью fetch, компонент перестает быть реактивным и больше не исчезает при изменении значения foo.visible:

<script>
    methods: {
        getDataFromApi() {
            return new Promise((resolve, reject) => {
                fetch(this.apiUrl)
                .then(response => {
                    return response.json();
                })
                .then(jsonResponse => {
                    resolve(jsonResponse);
                })
                .catch(e => {
                    ...
                })
            })
        },
        fillFoos() {
            this.getDataFromApi()
            .then(response => {
                response.forEach(data => {
                    this.foos.push(data);
                });
            });
        }
    },
    mounted: {
        this.fillFoos()
    }
    ...
</script>

В обоих случаях массив "foos" правильно заполнен, единственное отличие состоит в том, что директива v-if, по-видимому, нарушена во втором случае. Точнее, отображение выполняется правильно при инициализации (foo.visible истинно для всех элементов, и все они отображаются), но в случае более позднего изменения значения foo.visible они не исчезают.

Я не могу найти, что неправильно...

  • 0
    В вашем шаблонном теге, где вы используете v-for является ли этот шаблонный тег для файла .vue ? Кроме того, можете ли вы поделиться полезной нагрузкой, которую вы получаете, когда выполняете обещание?
  • 0
    Тег шаблона не является корневым элементом файла .vue (если вы это имели в виду)
Показать ещё 1 комментарий
Теги:
vue.js
fetch-api

2 ответа

1

Я считаю, что проблема, с которой вы сталкиваетесь, заключается в том, что метод getDataFromApi возвращает обещание, но когда вы его потребляете в fillFoos обещание не ожидается, вместо этого вы вызываете forEach на нем.

Вам нужно использовать getDataFromApi().then(x => {}) синтаксис для решения обещания или, альтернативно, вы можете использовать async await.

Вы можете попробовать что-то вроде этого

methods: {
    async getDataFromApi() {
        const response= await fetch(this.apiUrl);
        return response.json();
    },
    async fillFoos() {
        try {
            await foos = this.getDataFromApi();
            this.foos = foos;
        } catch(error) {
            //handle error.
        }
    }
}
  • 0
    Верный. response.json() - это Обещание, поскольку body может передаваться потоком.
  • 0
    Извините, на самом деле я использую затем после getDataFromApi, я забыл написать это в посте (сейчас исправлено)
Показать ещё 4 комментария
0

Вчера кто-то опубликовал ответ, очень близкий к решению, но удалил его, я не знаю, почему. Проблема заключалась в том, что я сохранил ответ на выборку в переменной в разделе данных, прежде чем использовать ее для заполнения таблицы "foos"

data: function() {
    return {
        dataFromApi: null
    }
}

Удалив эту переменную и, таким образом, создав ее на лету после извлечения, все работает нормально.... Я не указывал, что я сохранил ответ в этой переменной, потому что я не думал, что это может быть связано... Мораль: всегда указывайте все!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню