API автозаполнения адресов Google в Stenciljs

#google-api #stenciljs

#google-api #stenciljs

Вопрос:

Я пытаюсь добавить поле поиска для адреса, используя автозаполнение адреса Google в компоненте Stenciljs. На нем нет никаких ресурсов.

Ответ №1:

Сначала вам нужно будет загрузить скрипт Google maps api, чтобы вы могли взаимодействовать с глобальным google.maps объектом. Вы можете либо сделать это, включив тег script, либо написать что-то вроде следующей вспомогательной функции.

 const googleApiKey = '...';

export const importMapsApi = async () =>
    new Promise<typeof google.maps>((resolve, reject) => {
        if ('google' in window) {
            return resolve(google.maps);
        }

        const script = document.createElement('script');

        script.onload = () => resolve(google.maps);
        script.onerror = reject;
        script.src = `https://maps.googleapis.com/maps/api/js?key=${googleApiKey}amp;libraries=places`;

        document.body.appendChild(script);
    });
 

Чтобы получить типы TypeScript для глобального google объекта, вы должны установить @types/googlemaps их в свои dev-зависимости.

Затем вам нужно будет реализовать функцию, которая позволяет вам искать места, например.:

 export const searchForPlaces = async (input: string, sessionToken: google.maps.places.AutocompleteSessionToken) => {
    const maps = await importMapsApi();

    const service = new maps.places.AutocompleteService();

    return new Promise<google.maps.places.AutocompletePrediction[]>((resolve) =>
        service.getPlacePredictions({ input, sessionToken }, (predictions, status) => {
            if (status !== maps.places.PlacesServiceStatus.OK) {
                return resolve([]);
            }

            resolve(predictions);
        }),
    );
};
 

Ничто из этого не относится к Stencil btw. Все, что осталось сделать, это использовать searchForPlaces функцию в вашем компоненте. Очень простым примером может быть что-то вроде:

 @Component({ tag: 'maps-place-search' })
export class MapsPlaceSearch {
    sessionToken: string;

    @State()
    predictions: google.maps.places.AutocompletePrediction[];

    async componentWillLoad() {
        const maps = await importMapsApi();
        this.sessionToken = new maps.places.AutoCompleteSessionToken();
    }

    async search = (e: InputEvent) => {
        const searchTerm = e.target.value;

        if (!searchTerm) {
            this.predictions = [];
            return;
        }

        this.predictions = await searchForPlaces(searchTerm, this.sessionToken);
    }

    render() {
        return (
            <Fragment>
                <input onInput={this.search} />
                <ul>
                    {this.predictions.map(prediction => <li key={prediction.description}>{prediction.description}</li>)}
                </ul>
            <Fragment>
        );
    }
}
 

Поиск по месту даст вам placeId ответ на каждое предсказание. Это и токен сеанса, который вы можете передать a maps.places.PlacesService , чтобы получить подробную информацию о месте и автоматически заполнить свою форму или что-то еще, чего вы пытаетесь достичь.