I have a simple Vue component that displays an address, but converts into a form to edit the address if the user clicks a button. The address field is an autocomplete using Google Maps API. Because the field is hidden (actually nonexistent) half the time, I have to re-instantiate the autocomplete each time the field is shown.
<template>
<div>
<div v-if="editing">
<div><input ref="autocomplete" v-model="address"></div>
<button @click="save">Save</button>
</div>
<div v-else>
<p>{{ address }}</p>
<button @click="edit">Edit</button>
</div>
</div>
</template>
<script>
export default {
data() {
editing: false,
address: ""
},
methods: {
edit() {
this.editing = true;
this.initAutocomplete();
},
save() {
this.editing = false;
}
initAutocomplete() {
this.autocomplete = new google.maps.places.Autocomplete(this.$refs.autocomplete, {});
}
},
mounted() {
this.initAutocomplete();
}
}
I was getting errors that the autocomplete reference was not a valid HTMLInputElement, and when I did console.log(this.$refs) it only produced {} even though the input field was clearly present on screen. I then realized it was trying to reference a nonexistent field, so I then tried to confine the autocomplete init to only when the input field should be visible via v-if. Even with this, initAutocomplete() is still giving errors trying to reference a nonexistent field.
How can I ensure that the reference exists first?
Maybe a solution would be to use $nextTick which will wait for your DOM to rerender.
So your code would look like :
edit() {
this.editing = true;
this.$nextTick(() => { this.initAutocomplete(); });
},
Moreover if you try to use your this.initAutocomplete(); during mounting it cannot work since the $refs.autocomplete is not existing yet but I'm not sure you need it since your v-model is already empty.
I think it's because your "refs" is plural
<input refs="autocomplete" v-model="address">
It should be:
<input ref="autocomplete" v-model="address">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With