Reputation: 2066
I have this small one page VueJS app which uses Firebase. The problem I am currently facing is when I try to retrieve a collection from Firebase in a component. Instead of returning an array, the vue instance returns an observer object, more precisely [__ob__: Observer]
. I understand that Vue JS uses this object to do its magic, what I don't understand is what am I supposed to do to get the actual array. I cannot do anything with that object, can't iterate it. I tried any lifecycle method to try and do it, but no luck. What is weirder is that when I close and open again the Chrome console (F12), the methods get called again and the object is actually resolved into the array. I initially thought that the data may not be retrieved yet, but the data is present in the object itself, I just can't access it.
Here's my code:
Vue instance:
new Vue({
el: '#app',
firebase: {
orders: firebase.database.ref('orders').orderByChild('created_at'),
members: firebase.database.ref('members').orderByChild('created_at')
},
router,
template: '<App/>',
components: { App }
})
Component code:
export default {
data () {
return {
'member': null
}
},
computed: {
isMemberLoaded: function () {
this.member !== null
}
},
mounted: function () {
console.log('mounted')
this.init()
console.log(this.$root.members) // [__ob__: Observer]
},
created: function () {
console.log('created')
console.log(this.$root.members) // [__ob__: Observer]
},
updated: function () {
console.log('updated')
console.log(this.$root.members) // [__ob__: Observer]
},
methods: {
init: function () {
console.log('init')
console.log(this.$root.members) // [__ob__: Observer]
}
}
}
The observer object looks like this:
[__ob__: Observer]
0:
.key:(...)
code:(...)
created_at:(...)
email:(...)
name:(...)
__ob__:Observer {value: {…}, dep: Dep, vmCount: 0}
get .key: ƒ reactiveGetter()
set .key: ƒ reactiveSetter(newVal)
get code: ƒ reactiveGetter()
set code: ƒ reactiveSetter(newVal)
get created_at: ƒ reactiveGetter()
set created_at: ƒ reactiveSetter(newVal)
get email: ƒ reactiveGetter()
set email: ƒ reactiveSetter(newVal)
get name: ƒ reactiveGetter()
set name: ƒ reactiveSetter(newVal)
__proto__: Object
length: 1
__ob__: Observer {value: Array(1), dep: Dep, vmCount: 0}
__proto__: Array
What am I missing here?
Upvotes: 8
Views: 18909
Reputation: 1577
Simply do:
var parsedObj = JSON.parse(JSON.stringify(this.$root.members))
console.log(parsedObj)
It will convert the [ob: Observer] to its value
Upvotes: 5
Reputation: 2066
So, with the help of @Georgi Antonov I managed to solve my issue in this way:
I changed my component like this:
methods: {
init: function () {
let _vm = this
let _id = _vm.$route.params.id
_vm.$root.$firebaseRefs.members.child(_id).on('value', function (d) {
console.log(d.val())
})
}
}
The essential parts is _vm.$root.$firebaseRefs.members
. This actually resolves in a firebase object (collection?) and from there you can access the data. The child
function just retrieves the element with the passed id. It's not an array, but I don't require one as I don't need to search. In order to get the entire list just change to _vm.$root.$firebaseRefs.members.on('value', function() {}
.
While Georgi Antonov provided the answer above, that is not quite correct. The firebase references are defined in the Vue instance and you don't need to declare them again in the component. Hence, this
would not have the firebase refs in the scope.
Upvotes: 0
Reputation: 1641
I don't know how this firebase thing works. but im sure you can access the $firebase object with this
in each component because it is obviously global and find your data there.
export default {
data () {
return {
'member': null
}
},
firebase: {
members: db.ref('members')
},
computed: {
isMemberLoaded: function () {
this.member !== null
}
},
mounted: function () {
console.log('mounted')
this.init()
console.log(this.$root.members) // [__ob__: Observer]
},
created: function () {
console.log('created')
console.log(this.$root.members) // [__ob__: Observer]
},
updated: function () {
console.log('updated')
console.log(this.$root.members) // [__ob__: Observer]
},
methods: {
init: function () {
console.log('init')
console.log(this.$root.members) // [__ob__: Observer]
}
}
}
Upvotes: 0