Utilizing VueJS to effectively integrate the Google Places API with multiple references

I am currently integrating the Google Places API into my project and have encountered an interesting challenge. I need to implement multiple delivery addresses, requiring me to modify how the Google Places API functions.

Below is my existing code snippet:

<template>
  <div>
    <div v-for="(search, index) in searchInput" :key="index">
      <input type="text" ref="search" v-model="search.city">
    </div>
    <button type="button" @click="addMore">Add more</button>
  </div>
</template>

<script>
export default {
  name: "App",
  data: () => ({
    location: null,
    searchInput: [
      {
        city: ""
      }
    ]
  }),
  mounted() {
    window.checkAndAttachMapScript(this.initLocationSearch);
  },
  methods: {
    initLocationSearch() {
      let autocomplete = new window.google.maps.places.Autocomplete(
        this.$refs.search
      );
      autocomplete.addListener("place_changed", function() {
        let place = autocomplete.getPlace();
        if (place && place.address_components) {
          console.log(place.address_components);
        }
      });
    },
    addMore() {
      this.searchInput.push({ city: "" });
    }
  }
};
</script>

Encountering an error from the API with message:

InvalidValueError: not an instance of HTMLInputElement
and b.ownerDocument is undefined

I am seeking guidance on how to create unique references for each added item and pass them to the initLocationSearch method. Any insights or suggestions would be greatly appreciated.

View a demo on Codesandbox

Answer №1

Based on the information provided, here is my approach to solving the scenario.

To manage and display the inputs, I would implement a simple counter starting at 1.

<div v-for="(n, index) in this.counter" :key="index">
  <input type="text" ref="search">
</div>

The Autocomplete widget would be bound to the most recent input added using the counter.

autocomplete = new window.google.maps.places.Autocomplete(
  this.$refs.search[this.counter - 1]
);

An increment method like addMore() would be used to increase the counter value.

addMore() {
  this.counter++;
}

The updated() hook would trigger the initLocationSearch() method whenever a new input is appended to the DOM.

updated() {
  this.initLocationSearch();
},

Upon the place_changed event, the list of selected cities would be updated based on the input values.

this.selectedCities = this.$refs["search"].map(item => {
  return { city: item.value };
});

This setup ensures an accurate list of cities regardless of input changes, with consideration for edge cases such as empty inputs.

Full code implementation can be found below:

[Complete code snippet]

Explore demo on CodeSandbox

Answer №2

To establish a dynamic connection with a reference, you can use something along the lines of :ref="'search' + index"

<template>
  <div>
    <div v-for="(search, index) in searchInput" :key="index">
      <input type="text" :ref="'search' + index" v-model="search.city">
    </div>
    <button type="button" @click="addMore">Add more</button>
  </div>
</template>

When adding more input fields using addMore function, prior to appending a new object to searchInput array, retrieve the index of the last element in searchInput. This index can then be used to access the newly created reference and pass it to initLocationSearch.

    initLocationSearch(inputRef) {
      let autocomplete = new window.google.maps.places.Autocomplete(
        inputRef
      );
      autocomplete.addListener("place_changed", function() {
        let place = autocomplete.getPlace();
        if (place && place.address_components) {
          console.log(place.address_components);
        }
      });
    },
    addMore() {
      const lastInputRef = this.$refs['search' + this.searchInput.length - 1];
      this.initLocationSearch(lastInputRef);
      this.searchInput.push({ city: "" });
    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing Google's Recaptcha v2 to enhance website security and effectively prevent

My website incorporates an ajax form with Google reCAPTCHA. I have utilized event.preventDefault() to prevent the page from refreshing. Prior to integrating the captcha, everything functioned correctly. However, now whenever I attempt to submit the form, I ...

Invoke another component to display within a React.js application

Click here to view the code snippet. I am facing an issue with my React components. I have component A that handles fetching and rendering a list, and I also have component B that accepts user input. How can I trigger component A from component B? It seem ...

What is the best way to set up and customize multiple Vue Instances using Laravel Mix?

Currently, I am working on a PHP project that involves using Laravel and Vue.js. My main goal is to manage the Admin and Client functionalities separately by adding an additional Vue Instance. However, I am struggling with creating and setting up this in ...

Search across the entire table in your React application with Global

Having trouble implementing global search with the new Material UI Next table component. I have a handleSearch method that takes an event as a parameter and uses regex to check if the event.target.value matches any data in the table. However, when I dele ...

Retrieve data from a JSON object and assign it to a variable in JavaScript

I'm currently working on implementing AJAX to send and receive data in Django. My model consists of three fields: id, parent, and text. However, when attempting to post the information back to Django, I encounter an error due to additional fields pre ...

What is the best way to convert $('input[type=text]') into vanilla JavaScript?

How can I change this to plain JavaScript? I've been struggling to find a solution, any pointers? ...

Innovative idea for a time management system based on timelines and scheduling

My latest project involves creating a scrollable scheduler, inspired by vis-timeline and built using Vue.js. One of the main challenges I'm facing is achieving smooth infinite scrolling in all directions (past and future). I must confess that I&apo ...

Launching an online platform with Express and Ember frameworks

I am embarking on a project to create a straightforward CMS using Node.js (with Express) and Ember.js. While I have experience with Angular, I am new to Ember.js. I've noticed that Ember.js operates similarly to Angular in terms of its CLI reliance, a ...

Utilizing the correct method for binding checkboxes in Vue JS for effective two-way communication

I am working with data retrieved from a MySQL database where "1" and "0" represent boolean true and false. In my Vue component, I have set these values as shown below: data(){ return { form : { attribute_1 : "1", //attribute 1 is true ...

What is the best way for my partial components to interact with the main data object in Vue?

Currently, I am utilizing Vue Router to route external .vue files and link them with webpack. In my main.js file, I have an object that sets up my Vue instance. var vm = new Vue({ el: '#app', router, //render: h => h(App), data:{ ...

Placing a user's username within an ejs template using express and node.js

Currently, I am attempting to integrate the username into a layout using ejs templating with node and express. Below are the steps I have taken: Mongodb model: const mongoose = require('mongoose') const Schema = mongoose.Schema; var uniqueValid ...

Looking for assistance with JQuery and JavaScript?

I oversee a team of employees, each with a 7-day work schedule. To streamline the process, I have developed a PHP form that I would like to use to collect data for verification in JavaScript before submitting it to an SQL database using AJAX. My main cha ...

Utilizing React and Google Code to Enhance Lead Conversion Pages

I have developed a basic react application featuring a contact form. Upon submission, I aim to display the Google Code for the lead Conversion Page within the application. <!-- Google Code for Purchase Conversion Page --> <script type="text ...

Learn how to showcase a predetermined option in an HTML select element using Vue.js and Minimalect

I am currently utilizing Vue.js along with the Mininmalect HTML select plugin to showcase a list of countries by their names and values, where the value represents the 2 digit country code. Successfully, I have managed to implement the plugin for selectin ...

Instructions on how to invoke a function defined in a JavaScript module (type=module) from an HTML document

I've been facing difficulties with using JavaScript modules... I have an HTML file and a JS module. In the javascript file, I have a function defined that I want to call from my HTML page. Here is my code: index.html <html> <head> < ...

Unable to open Vue.js and Vuetify.js Accordion

Incorporating a custom component called blog, I utilized an accordion feature from vuetify.js to display blog posts within the component using another custom component, blog-post. Initially, everything worked smoothly without nesting the components togethe ...

Is Sending an Object to a Function in the Same Scope Inefficient?

Is there a noticeable delay when passing around an object within the same scope? Let's explore Option 1 and Option 2. In Option 1, we work directly with the object, while in Option 2 we follow better encapsulation practices. However, if we were to sti ...

comprehending the concept of express and mastering its usage

Can you confirm if my understanding is correct? 1) So, when I write this line of code... const express = require(“express”) I am assigning a "Class" to the variable express. 2) And then, when I call this function... express.jason() Am I correctly ...

How can I use a button created with jQuery's .html() method to conceal a <div>?

I am facing an issue with implementing a simple banner that should appear in an empty element only when specific values are returned by an Ajax call. In the banner, I want to include a Bootstrap button that hides the entire div when clicked. Due to my la ...

Substitute "Basic Authentication" with "Form Authentication"

Is there a way in W20 to switch from using "Basic Authentication" to "Form Authentication"? The current documentation mentions only the use of "basicAuth" and does not provide information on implementing form authentication. Our app is built with Angular ...