Vue JS возвращает данные [__ob__: Observer] вместо моего массива объектов

Я создал страницу, на которой хочу получить все свои данные из базы данных с помощью вызова API, но я тоже новичок в VueJS и Javascript, и я не знаю, где я ошибаюсь. Я проверил его с помощью Postman и получил обратно правильный JSON.

Вот что я получаю:

[__ob__: Observer]
length: 0
__ob__: Observer {value: Array(0), dep: Dep, vmCount: 0}
__proto__: Array

Вот чего я хочу:

(140) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …]
[0 … 99]
[100 … 139]
length: 140
__ob__: Observer {value: Array(140), dep: Dep, vmCount: 0}
__proto__: Array

Это мой файл шаблона Vue:

<template>
    <div>
        <h2>Pigeons in the racing loft</h2>
        <div class = "card-content m-b-20" v-for = "pigeon in pigeons" v-bind:key = "pigeon.id">
            <h3>{{ pigeon.id }}</h3>
        </div>
    </div>
</template>

<script>
export default {
    data(){
        return{
            pigeons: [],
            pigeon: {
                id: '',
                sex: '',
                color_id: '',
                pattern_id: '',
                user_id: '',
                loft_id: '',
                country: '',
                experience: '',
                form: '',
                fatique: ''
            },
            pigeon_id: ''
        }
    },
    created(){
        this.fetchPigeons();
        console.info(this.pigeons); // Here I got the observer data instead my array
    },

    methods: {
        fetchPigeons(){
            fetch('api/racingloft')
            .then(res => res.json())
            .then(res => {
                console.info(res.data); // Here I get what I need
                this.pigeons = res.data;
            })
        }
    }
}
</script>

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

попробуйте заменить console.info в созданной функции на

F_Mekk 18.10.2018 14:08

Вы пытаетесь зарегистрировать данные в created () до завершения асинхронной выборки, поэтому он все еще пуст (за исключением Observable, который Vue использует для обнаружения изменений в данных, например, когда выборка завершается, чтобы он мог повторно визуализировать компонент.)

Daniel Beck 18.10.2018 22:13
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
106
2
106 394
12

Ответы 12

Вероятно, вам следует дождаться завершения выборки, а затем console.info результат ..

created(){
    this.fetchPigeons().then(() => console.info(this.pigeons));
},

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

Редактировать: Также, как указал @barbsan в своем комментарии ниже, ваш fetchPigeons должен возвращать обещание, что then будет работать. fetch возвращает обещание, поэтому вам просто нужно вернуть выборку в fetchPigeons

fetchPigeons(){
    return fetch('api/racingloft')
    .then(res => res.json())
    .then(res => {
        console.info(res.data); // Here I get what I need
        this.pigeons = res.data;
    })
}

[Предупреждение Vue]: Ошибка в созданном хуке: «TypeError: Невозможно прочитать свойство 'then' of undefined», обнаруженное в ---> <Pigeons> в resources / js / components / Pigeons.vue <Root> Я понял. Ни консоль, ни рендеринг не показывают мне, что у меня есть объекты.

shawnest 18.10.2018 14:10

@HusamIbrahim fetchPigeons не возвращает обещание, вам также необходимо добавить return перед fetch

barbsan 18.10.2018 14:21

@barbsan Спасибо, что указали на это. Я пропустил эту часть. +1

Husam Ibrahim 18.10.2018 14:34

На самом деле return устранил проблему, но я все еще не могу отобразить ее на странице. я не знаю, в чем проблема. Я слежу за сериалом видео на YouTube, и он просто работает без возврата. Не знаю, что я неправильно настроил. Он также показывает им информацию о данных Vuejs в инструментах vue dev, в то время как я вижу только <root> = $ vm0 и ничего больше, даже если я нажимаю на него.

shawnest 18.10.2018 18:00

Проблема должна быть легко решаемой, потому что, если я настрою переменную сообщения и установлю ее как {{message}}, она действительно появится на странице. Но если я просто изменяю данные с помощью created или connected, я просто получаю пустой массив, поэтому я ничего не визуализирую.

shawnest 18.10.2018 18:30

@shawnes Ваш массив голубей все еще пуст после вызова fetch?

Husam Ibrahim 18.10.2018 18:37

created () {this.fetchPigeons (). then (() => console.info (this.pigeons)); } После этого я получил массив обратно. Но когда я добавляю {{голубей}} в шаблон, появляется {}.

shawnest 18.10.2018 18:54

@shawnest Вы используете v-for = "pigeon in pigeons", поэтому вы должны использовать голубя в своем шаблоне с любым полем, которое вы хотите отобразить. Так что, если есть поле id, вы должны сделать {{pigeon.id}}.

Husam Ibrahim 18.10.2018 19:01

Это в моем шаблоне vue: <div class = "card-content mb-20" v-for = "голубь в голубях" v-bind: key = "pigeon.id"> <h3> {{pigeon.id}} </h3> </div>

shawnest 18.10.2018 19:25

@shawnest Убедитесь, что у ваших объектов массива есть поле id.

Husam Ibrahim 18.10.2018 19:29

Я не знаю, что могу неправильно настроить его где-то в моем каталоге laravel.

shawnest 18.10.2018 21:26

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

Husam Ibrahim 18.10.2018 21:35

Это происходит потому, что Vue js преобразует каждый элемент данных во что-то, что можно наблюдать. Так что имеет смысл, если вы консоль регистрируете что-то в данных. Результатом будет нечто, заключенное в наблюдателя.

Чтобы лучше видеть ваши данные, я предлагаю вам установить инструменты Vue dev. https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en

Да, спасибо. Я использую инструменты Vue dev. Но когда я использую его, я вижу только <Root> = $ vm0, больше ничего, даже если я нажимаю на него.

shawnest 18.10.2018 17:58

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

Kevin LE GOFF 19.10.2018 10:23

Вы можете использовать директиву v-if для рендеринга компонента, когда там есть данные.

<h3 v-if = "pigeons.length > 0">{{ pigeon.id }}</h3>

Также можно попробовать это:

var parsedobj = JSON.parse(JSON.stringify(obj))
console.info(parsedobj)

Его принес сам Эван Ю здесь и больше информации об этом здесь

Но ждать ответа - это первый шаг.

почему это не помогает мне и тому, кто задавал проблему, решить проблему? Я пробовал все ответы снизу, кроме stackoverflow.com/a/56013942/5057913. как не мог понять, где хранить код. Я получаю пустой массив, когда использую приведенный выше код, когда у меня есть массив, полный значения для этого наблюдателя

Saugat Thapa 19.04.2020 14:13

Вот мое решение:

добавьте новый метод, например log, в ваш компонент $ root. App.vuecreated рекомендуется:

this.$root.log = function log() {
  for (let i = 0; i < arguments.length; i += 1) {
    if (typeof (arguments[i]) === 'object') {
      try {
        arguments[i] = JSON.parse(JSON.stringify(arguments[i]));
      } catch (e) {
        console.error(e);
      }
    }
  }
  console.info(...arguments);
};

просто вызовите this.$root.log(this.pigeons) в своем компоненте.

Мой результат:

ДО:

ПОСЛЕ:

Как упоминал Хусам Ибрагим, вам следует дождаться разрешения функции async fetch (). Другой подход может заключаться в использовании async / await в вашей функции:

methods: {
    async fetchPigeons(){
        await fetch('api/racingloft')
               .then(res => res.json())
               .then(res => {
                   console.info(res.data);
                   this.pigeons = res.data;
               })
    }
}

И тогда должно работать:

<template>
  <div>
    <h2>Pigeons in the racing loft</h2>
    <div class = "card-content m-b-20" v-for = "pigeon in pigeons" v-bind:key = "pigeon.id">
        <h3>{{ pigeon.id }}</h3>
    </div>
  </div>
</template>

Можем ли мы использовать стандартные обещания вместо await?

Shamoon 16.07.2019 17:59

Конечно, но вам, возможно, придется обрабатывать разрешение обещания в другой функции.

Andre Ravazzi 09.09.2020 17:25

Спасибо за все ваши предложения. С моей стороны все работало, просто используя "const".

const cookieInfo = ToolCookieService.getToolNumbersFromCookie();

Спасибо, Ранджит

Ну, у меня была точно такая же проблема, но я ее решил:

Просто переместите внешнюю ссылку app.js в тег заголовка.

У меня та же проблема все еще застряла ...

Написал их в соответствии с методом Эвана (Vue Author) JSON.parse (JSON.stringify (res.data)), но почему не могут нормальные данные?

  methods: {
    async getdata() {
      console.info(1);
      await axios.get(API).then((res) => {
          console.info(2);
          if (!this.dataList.length) {
            this.dataList = JSON.parse(JSON.stringify(res.data));
            console.info(3);
            console.info(res.data, 'res.data ');
            console.info(this.dataList, 'this.dataList')
            console.info('----------check-----------',JSON.parse(JSON.stringify(res.data)));
          }
        })
        .catch(err => {
          console.error('failed: ' + err);
        })
      console.info(4);
    },

Если ваша цель - отладка того, ЧТО включено в экземпляр Observer Vue, это мое решение:

Print out that variable in template block belongs to your Component

После этого вы можете переформатировать структуру вывода, чтобы рассмотреть детали.

Например:

<template>
  <div>
    {{ pigeons }}
  <div>
</template>

Другой способ, если вы хотите увидеть это в console, вы должны перевести console.info в фазу mounted. Потому что на этапе createdthis.pigeons все еще пуст. Ссылка: https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram

Надеюсь, это поможет.

Самый лучший способ

obj2 = JSON.stringify(obj)
obj3 = JSON.parse(obj2)

Или

obj2 = Object.assign([], obj)

Его принес сам Эван Ю здесь и подробнее

По сути, вы сделали то, что функция извлекает массив голубей, но, поскольку он работает параллельно, вы вызвали console.info. Легко исправить:

this.fetchPigeons().then(()=>{
  console.info(this.pigeons);
}

Другие вопросы по теме