Vue Google Maps - Array of InfoWindows On Click Open Details InfoWindow

I'm basically trying to implement a very similar looking map to Airbnb's. I have displayed an array of infowindows to display the price of each rental location. When I click on an infowindow I then display another infowindow (named popup) with the locations details.

I've added an event listener to the infowindow element however when I click ANY of the infowindows on the map I only get a popup of the last result in the array.

  methods: {
    initMap() {
      var map = new google.maps.Map(document.getElementById("camp-map"), {
        zoom: 2,
        center: { lat: this.latitude, lng: this.longitude },
        mapTypeId: 'satellite',
        zoomControl: true,
        zoomControlOptions: {
            position: google.maps.ControlPosition.RIGHT_BOTTOM
        },        
        mapTypeControl: false,
        scaleControl: false,
        streetViewControl: false,
        rotateControl: false,
        fullscreenControl: false
      });

      this.popup = new google.maps.InfoWindow({
        content: "nothing yet..."
      });

      return map;
    },

    addInfoWindows(map) {    
      // Get total lat & total lng to center the map on new results
      let totalLat = 0;
      let totalLng = 0;

      // Iterate over all of the camps
      for (var i = 0; i < this.filteredCamps.length; i++) {

        let latitude = this.filteredCamps[i].coordinates.lat;
        let longitude = this.filteredCamps[i].coordinates.lng;

        let id = this.filteredCamps[i].id;
        let slug = this.filteredCamps[i].slug;
        let name = this.filteredCamps[i].name;
        let price = this.filteredCamps[i].priceAvg.toLocaleString("en");
        let image = this.filteredCamps[i].mainImage;
        let country = this.filteredCamps[i].country;
        let type = this.filteredCamps[i].type;

        totalLat += parseFloat(latitude);
        totalLng += parseFloat(longitude); 

        // create a HTML element for each spot
        var el = document.createElement("div");
        el.innerHTML =
          '<div><div class="marker-tooltip"></div>$' + price + "</div>";

        el.className = "camp-map-marker";

        var infowindow = new google.maps.InfoWindow({
          content: el,
          position: { lat: latitude, lng: longitude },
          map: this.map,
        });

        // Create popup view
        var div = .... 

        this.popup = new google.maps.InfoWindow({
          content: div,
          position: { lat: latitude, lng: longitude },
        });

        // On infowindow click center and popup
        el.addEventListener("click", () => {
          console.log('clicked: ')
          this.map.setCenter({ lng: longitude, lat: latitude })
          this.popup.setContent(div);
          this.popup.open(this.map, infowindow) 
        });         

        this.gMarkers.push(infowindow);
      }

      let arrayLength = this.gMarkers.length
      let currentLat = totalLat / arrayLength
      let currentLng = totalLng / arrayLength
      this.map.setCenter({ lat: currentLat, lng: currentLng }); 
    },

1 answer

  • answered 2019-03-14 03:52 Skipper

    You do it in the loop, so when loop is over the popup has the last value:

     this.popup = new google.maps.InfoWindow({
          content: div,
          position: { lat: latitude, lng: longitude },
        });
    

    From here:

    let latitude = this.filteredCamps[i].coordinates.lat;
    let longitude = this.filteredCamps[i].coordinates.lng;
    

    where

    i = this.filteredCamps.length
    

    when loop is over.

    You need to create a new popup for every point (but it's resource-consuming), or create a new popup every time when you click on a marker. For the second one create a separate function, pass some data to it and create a new popup.

    Hope, it helps.