J. Jackson
J. Jackson

Reputation: 3774

How to use Mapbox geocoder with Quasar select?

I'm trying to create an Autocomplete component using the Mapbox Geocode API and Quasar's <q-select /> component. It appears though that Mapbox requires using their input (could be wrong about this), so I'm having trouble hooking it up to the select.

I've tried using the @mapbox/mapbox-gl-geocoder, vue-mapbox-ts and v-mapbox-geocoder libraries now. The two third-party libraries had some issues with them, so I'd prefer to use the one direct from Mapbox if possible.

<template>
  <q-select
    v-model="state.location"
    :options="state.locations?.features"
    :option-value="(result: MapboxGeocoder.Result) => result.place_name"
    :option_label="(result: MapboxGeocoder.Result) => result.place_name"
    :loading="state.loadingResults"
    clear-icon="clear"
    dropdown-icon="expand_more"
    clearable
    outlined
    use-input
    dense
    label="Location">
      <template #prepend>
        <q-icon name="place " />
      </template>
  </q-select>
</template>

<script lang='ts' setup>
  import { reactive, ref, onMounted } from 'vue';
  import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';

  const accessToken = import.meta.env.VITE_MAPBOX_ACCESS_TOKEN as string;

  const state = reactive({
    first_name: auth.currentUser?.first_name || undefined,
    last_name: auth.currentUser?.last_name || undefined,
    location: undefined,
    locations: undefined as undefined | MapboxGeocoder.Results,
    loadingResults: false,
    geocoder: null as null | MapboxGeocoder,
  });

  onMounted(() => {
    state.geocoder = new MapboxGeocoder({
      accessToken,
      types: 'country,region,place,postcode,locality,neighborhood',
    });

    state.geocoder?.on('result', (e) => {
      console.log('on result: ', e);
    });

    state.geocoder?.on('results', (e) => {
      console.log('results: ', e);
      state.locations = e.features;
    });

    state.geocoder?.on('loading', (e) => {
      console.log('loading');
      state.loadingResults = true;
    });
  });
</script>

In the code sample above, none of the console logs are being run. If I add an empty <div id="geocoder" /> and then use the state.geocoder.addTo('#geocoder') function, it renders the Mapbox input and hits the console logs, but then I am unable to use the Quasar select like I'm hoping to.

How can I go about accomplishing this?

Upvotes: 2

Views: 259

Answers (2)

manuel-ch
manuel-ch

Reputation: 11

MapboxGeocoder is a UI control, it's not meant to be used in a "headless" mode.

As you create your own control, you could just use the Mapbox Geocoder API, see https://docs.mapbox.com/api/search/geocoding/ for more information on how this works.

Upvotes: 0

Jay Borseth
Jay Borseth

Reputation: 2003

I never tracked down the reason why your seemingly correct syntax failed, but if I used this alternative:

const function results(e) {
  console.log('results: ', e);
  state.locations = e.features;
}

state.geocoder?.on('results', results);

everything magically worked.

Upvotes: 0

Related Questions