Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js this.$refs empty due to v-if

Tags:

vue.js

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?

like image 434
Erich Avatar asked Nov 15 '25 05:11

Erich


2 Answers

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.

like image 120
Baldráni Avatar answered Nov 17 '25 19:11

Baldráni


I think it's because your "refs" is plural

<input refs="autocomplete" v-model="address">

It should be:

<input ref="autocomplete" v-model="address">
like image 41
BakaDesu Avatar answered Nov 17 '25 18:11

BakaDesu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!