inocan-group / vue3-google-map

A set of composable components for easy use of Google Maps in your Vue 3 projects.
https://vue3-google-map.com
MIT License
295 stars 60 forks source link

Autocomplete Feature #255

Closed sbautista05 closed 3 months ago

sbautista05 commented 6 months ago

Hello, I would like to ask if there will be any future plans to have an autocomplete feature from google maps? Such as what is stated in the google maps documentation? https://developers.google.com/maps/documentation/javascript/reference/places-autocomplete-service

azadbilge commented 4 months ago

I have seen this feature is not implemented yet. So I did this this for myself. This feature can be done by fetching directly google maps api links. A Basic example with primevue Autocomplete component.

<script setup>
// ...
const searchTimeOut = ref()
const selectedPlace = ref({})
const resultPlaces = ref([])

const search = async (event) => {
  if(searchTimeOut.value) {
    clearTimeout(searchTimeOut.value)
  }

  searchTimeOut.value = setTimeout(async () => {
    const placeResult = await fetch(`http://localhost:3001/map/place/${event.query}`)
    const googleMapResult = await placeResult.json()
    // There Are found places
    resultPlaces.value = googleMapResult.data
  }, 1000)
}

watch(selectedPlace, () => {
  if(typeof selectedPlace.value === 'object') {
    // Select a place from google map place results
    props.blockContent.place = selectedPlace.value
  }

})
// ...
</script>
<template>

  <div class="flex flex-column flex-wrap gap-2 w-full" >
    <AutoComplete v-model="selectedPlace" optionLabel="name" :suggestions="resultPlaces" @complete="search">
      <template #option="slotProps">
          <div class="flex align-options-center" style="width: 15rem;">
              <span class="font-semibold">{{ slotProps.option.name }}</span>
              <span>{{ "&nbsp-&nbsp" + slotProps.option.address }}</span>
          </div>
      </template>
    </AutoComplete>

    <div v-if="typeof selectedPlace === 'object'" class="flex flex-column">
      <div>
        <span class="font-semibold">Address:&nbsp</span>
        <span>{{ selectedPlace.address  }}</span>
      </div>
      <div>
        <span class="font-semibold">Location:&nbsp</span>
        <span>{{ selectedPlace.location.lat + "," + selectedPlace.location.lng  }}</span>
      </div>
    </div>
  </div>
<!-- ... -->
</template>

As you can see there is a fetch request to my api server due to google maps api cors issue. Requests has to be called in nodejs

const resGMap = await fetch(`https://maps.googleapis.com/maps/api/place/textsearch/json?query=${req.params.query}&radius=100&sensor=true&key=${process.env.GMAPS_API_KEY}`)
  const resJson = await resGMap.json()
  res.json({
    'success': true,
    "data": resJson.results.map(result => {
      return {
        name: result.name,
        location: {
          lat: result.geometry.location.lat,
          lng: result.geometry.location.lng
        },
        address: result.formatted_address,
        place_id: result.place_id
      }
    })
  })
HusamElbashir commented 3 months ago

Duplicate of #195