Vue JS returns [__ob__: Observer] data instead of my array of objects
Solution 1
Can also try this:
var parsedobj = JSON.parse(JSON.stringify(obj))
console.log(parsedobj)
It was brought by Evan You himself here and more info on that here
But waiting for the answer is a first step.
Solution 2
This happens because Vue js convert every item in the data to something that can be observed. So it makes sense if you console log something in the data. The output will be something wrapped into an observer.
To have a better vision on your data I suggest you to install the Vue dev tools. https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en
Solution 3
Here is my solution:
add new method something like log
to your $root component. App.vue
's created
is recommended:
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.log(...arguments);
};
just call this.$root.log(this.pigeons)
in your component.
My result:
BEFORE:
AFTER:
Solution 4
You should probably wait for the fetch to finish then console.log the result ..
created(){
this.fetchPigeons().then(() => console.log(this.pigeons));
},
The way you were doing it you were logging the result synchronously so it gets executed before the fetch is done.
Edit: Also as @barbsan pointed out in his comment below your fetchPigeons
needs to return a promise for then
to work. fetch
returns a promise so you just need to return fetch in fetchPigeons
fetchPigeons(){
return fetch('api/racingloft')
.then(res => res.json())
.then(res => {
console.log(res.data); // Here I get what I need
this.pigeons = res.data;
})
}
Solution 5
The best way possible
obj2 = JSON.stringify(obj)
obj3 = JSON.parse(obj2)
Or
obj2 = Object.assign([], obj)
It was brought by Evan You himself here and more info
Related videos on Youtube
shawnest
Updated on July 08, 2022Comments
-
shawnest almost 2 years
I've created a page where I want to get all my data from the database with an API call, but I'm kinda new to VueJS and Javascript aswell and I don't know where I'm getting it wrong. I did test it with Postman and I get the correct JSON back.
This is what I get:
[__ob__: Observer] length: 0 __ob__: Observer {value: Array(0), dep: Dep, vmCount: 0} __proto__: Array
This is what I want:
(140) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …] [0 … 99] [100 … 139] length: 140 __ob__: Observer {value: Array(140), dep: Dep, vmCount: 0} __proto__: Array
Thats my Vue template file:
<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.log(this.pigeons); // Here I got the observer data instead my array }, methods: { fetchPigeons(){ fetch('api/racingloft') .then(res => res.json()) .then(res => { console.log(res.data); // Here I get what I need this.pigeons = res.data; }) } } } </script>
I've tried to do it with axios aswell, but it gave me exactly the same thing. When I console it from the method it gives my data, but outside it just gives nothing.
-
F_Mekk over 5 yearstry to replace the console.log in the created function by
-
Daniel Beck over 5 yearsYou're trying to log the data in created() before the asynchronous fetch completes, so it's still empty (except for the Observable that Vue uses to detect changes in the data, such as when the fetch completes, so it can re-render the component.)
-
Evgeny Malkov over 2 yearsSo, what was the problem? Catched same bug today
-
-
shawnest over 5 years[Vue warn]: Error in created hook: "TypeError: Cannot read property 'then' of undefined" found in ---> <Pigeons> at resources/js/components/Pigeons.vue <Root> I get this one. Neither the console, nor the rendering shows me that I have objects.
-
barbsan over 5 years@HusamIbrahim
fetchPigeons
doesn't return promise, you need also to addreturn
beforefetch
-
Husam Ibrahim over 5 years@barbsan Thanks for pointing that out. I missed that part. +1
-
shawnest over 5 yearsYes thanks. I use Vue dev tools. But when I use it I only see <Root> =$vm0, nothing else even if I click on it.
-
shawnest over 5 yearsActually return fixed the issue, but I still can't render it to the page. i dont know what the problem is. Im following youtube video series, and it just works without the return aswell. I don't know what I set up incorrectly. It also shows them info about the Vuejs datas in vue dev tools, while I only see <root> = $vm0 and nothing else even if I click on it.
-
shawnest over 5 yearsThe problem must be easy to solve because if I set up a message variable and set it up as {{message}}, it does show up in the page. But If I just modify data with created or mounted I just get back an empty array, thats why I doesnt render anything.
-
Husam Ibrahim over 5 years@shawnes Is your pigeons array still empty after the fetch call?
-
shawnest over 5 yearscreated(){ this.fetchPigeons().then(() => console.log(this.pigeons)); } After this I got the array back. But when I put like {{ pigeons }} into the template it shows {}.
-
Husam Ibrahim over 5 years@shawnest You are doing
v-for="pigeon in pigeons"
so you should use pigeon inside your template with whatever field you want to display. So if there's an id field you would do {{ pigeon.id }}. -
shawnest over 5 yearsThis is in my vue template: <div class="card-content m-b-20" v-for="pigeon in pigeons" v-bind:key="pigeon.id"> <h3>{{ pigeon.id }}</h3> </div>
-
Husam Ibrahim over 5 years@shawnest Please verify that your array objects have an id field.
-
shawnest over 5 yearsI don't know I might set it up wrongly somewhere in my laravel directory.
-
Husam Ibrahim over 5 years@shawnest You might want to post a new question with all the relevant code for better exposure and for people to see why your data isn't rendering properly. Otherwise they're mostly going to glance over this question and you won't get much help since the question is about a separate issue.
-
Kevin LE GOFF over 5 yearsAre you looking at the good component? Could you add a screenshot of what you see in the dev tools. It will help to figure out what is going on.
-
Shamoon almost 5 yearsCan we use standard promises instead of
await
? -
Saugat Thapa about 4 yearswhy doesnt this help me and one who asked the problem, solve the problem? i tried all of the asnwer from below except stackoverflow.com/a/56013942/5057913. how couldnt figuer out where to keep the code. i get empty array when i use teh above code when i do have array sfull of value on that observer
-
Andre Ravazzi over 3 yearsFor sure, but you will have to handle the promise resolution in another function maybe.
-
tahnoon over 2 yearsThis fixed my problem, thank you.