vuejs3google-places-apiquasar-frameworkquasargoogle-places-autocomplete

VueJS + Quasar Framework + Google Places Autocomplete = InvalidValueError: not an instance of HTMLInputElement


trying to implement the google autocomplete to my address form. I'm using the Quasar framework, can't find the sulution for: InvalidValueError: not an instance of HTMLInputElement

Below my address form and all scripts relevent:

<script src="https://maps.googleapis.com/maps/api/js?key=MY_API_TOKEN&libraries=places"></script>
<template>
  <q-card-section class="q-pt-none">
    <q-form @submit="save" class="q-gutter-md">
      <q-input
        filled
        v-model="modelAddress.title"
        :label="$t('address_title_label')"
        :hint="$t('address_title_hint')"
        lazy-rules
        :rules="[isNotEmpty]"
      />
      <q-input
        filled
        v-model="modelAddress.country"
        :label="$t('address_country_label')"
        :hint="$t('address_country_hint')"
        lazy-rules
        :rules="[isNotEmpty]"
      />
      <q-input
        filled
        v-model="modelAddress.city"
        :label="$t('address_city_label')"
        :hint="$t('address_city_hint')"
        lazy-rules
        :rules="[isNotEmpty, isCityOrPostalCode]"
      />
      <q-input
        filled
        v-model="modelAddress.code"
        :label="$t('address_code_label')"
        :hint="$t('address_code_hint')"
        lazy-rules
        :rules="[isNotEmpty]"
      />
      <q-input
        filled
        v-model="modelAddress.street"
        ref="streetRef"
        id="streetRef"
        :label="$t('address_street_label')"
        :hint="$t('address_street_hint')"
        lazy-rules
        :rules="[isNotEmpty]"
      />
      <q-input
        filled
        v-model="modelAddress.number"
        :label="$t('address_number_label')"
        :hint="$t('address_number_hint')"
        lazy-rules
        :rules="[isNotEmpty]"
      />
      <div class="address-form-btn">
        <q-btn color="primary" :label="$t('save_btn')" type="submit" />
      </div>
    </q-form>
  </q-card-section>
</template>

<script>
/* eslint-disable */
import { defineComponent, onMounted, ref } from "vue"

export default defineComponent({
  name: "AddressFrom",
  setup () {
    const streetRef = ref()
    onMounted(() => {
      const autocomplete = new google.maps.places.Autocomplete(streetRef.value, {
        types: ['address'], 
        fields: ['address_components']
      })
    })
    return { streetRef }
  },
  data() {
    return {
      modelAddress: this.address
    }
  },
  props: {
    address: {
      type: String,
      default: "",
    },
  },
  methods: {
    save() {
      this.$emit("save", this.$data.modelAddress)
    },
    isNotEmpty(val) {
      if (!val) {
        return this.$t("please_pick_something")
      }
    }
  }
})
</script>

Hope this question is generic so also others can benefit


Solution

  • Not sure if my solution is the most elegant, but it's working:

    so below quasar input setup:

    <q-input
     v-model="modelAddress.street"
     ref="streetRef"
     @keypress="autocompleteLocation"
    />
    

    And needed methods:

    setup () {
     return { 
      streetRef: ref()
     }
    },
    methods: {
     autocompleteLocation () {
      const autocomplete = new google.maps.places.Autocomplete(this.streetRef.getNativeElement(), {
       types: ['address'], 
       fields: ['address_components']
      })
     }
    }
    

    Also after the API was returning queries it was not visible I needed to add below class style to return new google component which show up with the response:

    <style scope>
    .pac-container {
      z-index: 9999 !important;
    }
    </style>
    

    If you have similar problems, you can also see this quasar form post for additional inspiration: https://forum.quasar-framework.org/topic/7541/google-places-autocomplete-using-q-input-not-working-but-works-with-input

    Hope this helps.