I’m setting up a Vue.js project and connecting it to Firebase for the real time database.
Problem: when able to save the data to the Firebase database however when not able to render it to the view.
Error Message:
[vue.js warn]: Property or method “names” is not defined on the instance
but referenced during render.
there is tried to adjust the vue.js instance “names” property by adding it the data function instead of making it a separate property in the instance, but that is not working.
<div id=”app”>
<label for=””>Name</label>
<input type=”text” name=”” id=”” v-model=”name”>
<button @click=”submitName()”>Submit</button>
<div>
<ul>
<li v-for=”personName of names”
v-bind:key=”personName[‘.key’]“>
{personName.name}
</li>
</ul>
</div>
</div>
<script>
import {namesRef} from ‘./firebase’
export default {
name: ‘app’,
data () {
return {
name: “levi”,
}
},
firebase: {
names: namesRef
},
methods: {
submitName() {
namesRef.push( {name:this.name, edit:false} )
}
}
}
</script>
<style>
Expected Result: Data saved to Firebase is rendered on the view
Actual result:
[vue.js warn]: Property or method “names” is not defined on the instance
but referenced during render. Make sure that this property is
reactive, either in the data option, or for class-based components, by
initializing the property.
Solution :
Try this.
You need to return the object in data
<script>
import {namesRef} from ‘./firebase’
export default {
name: ‘app’,
data () {
return {
name: “levi”,
firebase: {
names: namesRef
},
}
},
methods: {
submitName() {
namesRef.push( {name:this.name, edit:false} )
}
}
}
</script>
<style>
Solution 2:
Essentially, you have an incorrect attribute in the vue.js instance.. You need to move firebase into data..
([CodePen])
I was unable to get this working in a Stack Snippet..
~THE FIX~
VUE/JS
firebase.initializeApp({
databaseURL: “https://UR-DATABASE.firebaseio.com",
projectId: “UR-DATABASE”
});
const database = firebase.database().ref(“/users”);
const vm = new Vue({
el: “#app”,
data: {
firebase: {
names: []
},
name: “SomeName”
},
methods: {
getFirebaseUsers() {
this.firebase.names = [];
database.once(“value”, users => {
users.forEach(user => {
this.firebase.names.push({
name: user.child(“name”).val(),
id: user.child(“id”).val()
});
});
});
},
handleNameAdd() {
let id = this.generateId();
database.push({
name: this.name,
id: id
});
this.name = “”;
this.getFirebaseUsers();
},
generateId() {
let dt = new Date().getTime();
return “xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx”.replace(/[xy]/g, c => {
let r = ((dt + Math.random() * 16) % 16) | 0;
dt = Math.floor(dt / 16);
return (c == “x” ? r : (r & 0x3) | 0x8).toString(16);
});
}
},
mounted() {
this.getFirebaseUsers();
}
});
HTML
<script src=”https://www.gstatic.com/firebasejs/6.1.1/firebase.js"> .
</script>
<div id=”app”>
<label for=””>Name</label>
<input type=”text” name=”” id=”” v-model=”name”>
<button @click=”handleNameAdd”>Submit</button>
<div>
<ul>
<li v-for=”(person, index) in firebase.names”
v-bind:key=”person.id”>
{person.name} | {person.id}
</li>
</ul>
</div>
</div>
OLD ANSWER:
This is what it should look like inside of data:
…
data() {
firebase: {
names: [],
}
}
…
Therefore, the data in the v-for would be referenced via firebase.names like:
…
<li v-for=”(personName, index) in firebase.names”
:key=”index”> // <<– INDEX IS NOT THE BEST WAY TO STORE KEYS BUT ITS BETTER THAN NOTHING
//:key=”personName.id // <<– YOU COULD ALSO DO SOMETHING LIKE THAT, IF YOU HAVE A UNIQUE ID PER PERSON
{personName.name}
</li>
…
OPTIMAL FIX:
You could use a computed property if you wanted to automatically save/retrieve data from firebase each time a user adds a new name…as outlined in the CodePen and Code Snippet..
THE ISSUE:
<script>
import {namesRef} from ‘./firebase’
export default {
name: ‘app’,
data () {
return {
name: “levi”,
}
},
firebase: { // <<— THIS IS INVALID, AND WHY IT’S NOT RENDERING
names: namesRef // CHECK the CONSOLE FOR ERRORS
},
methods: {
submitName() {
namesRef.push( {name:this.name, edit:false} )
}
}
}
</script>
Solution 3:
Use a computed property for names. Computed is more appropriate than data in this case, mainly because the component does not own the data. If it eventually resided in a vuex store, for instance, it would then react to external changes.
<script>
import {namesRef} from ‘./firebase’
export default {
name: ‘app’,
data () {
return {
name: “levi”,
}
},
computed: {
names() {
return namesRef
}
}
methods: {
submitName() {
namesRef.push( {name:this.name, edit:false} )
}
}
}
</script>
Solution 4:
Try this
<script>
import {namesRef} from ‘./firebase’
export default {
name: ‘app’,
data () {
return {
name: “levi”,
}
},
cumputed: {
names: namesRef
},
methods: {
submitName() {
namesRef.push( {name:this.name, edit:false} )
}
}
}
</script>