API Google place autocomplete с помощью Laravel

В этом уроке я покажу вам, как можно создать автозаполняемый адрес с помощью API google place. Вы могли видеть на некоторых сайтах при заполнении формы адреса он автоматически предлагает адрес и при нажатии на него заполняет остальные поля, такие как street line1, street line2, city, state, postcode и т.д.

Итак, что нам нужно, чтобы следовать этому руководству?

  • Настройте проект laravel: composer create-project laravel/laravel googleautocomplete.
  • Установите Guzzle: composer require guzzlehttp/guzzle.
  • Действительный ключ API google
  • Ознакомьтесь с документами API google Place Autocomplete: Google Place Autocomplete Api

Давайте создадим контроллер с методом index, который возвращает форму

php artisan make:controller GoogleAutocompleteController
Вход в полноэкранный режим Выход из полноэкранного режима

GoogleAutocompleteController.php

<?php

namespace AppHttpControllers;

use IlluminateViewView;
use IlluminateHttpRequest;

class GoogleAutocompleteController extends Controller
{
    public function index(): View
    {
        return view('form');
    }
}
Войти в полноэкранный режим Выход из полноэкранного режима

Внутри resources/views/form.blade.php
Я создал простую форму с помощью bootstrap, в которой есть поле адрес улицы, поле города, поле штата, поле почтового индекса и поле страны.

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Google autocomplete</div>
                    <div class="card-body">
                        <div class="form-group">
                            <label for="streetaddress">Street address</label>
                            <input type="text" class="form-control ui-widget autocomplete-google" id="street_address_1">
                        </div>

                        <div class="form-group">
                            <label for="streetaddress2">Street address 2</label>
                            <input type="text" class="form-control" id="street_address_2">
                        </div>

                        <div class="form-group">
                            <label for="city">City</label>
                            <input type="text" class="form-control" id="city">
                        </div>

                        <div class="form-group">
                            <label for="state">State</label>
                            <input type="text" class="form-control" id="state">
                        </div>

                        <div class="form-group">
                            <label for="postcode">Postcode</label>
                            <input type="text" class="form-control" id="postcode">
                        </div>

                        <div class="form-group">
                            <label for="country">Country</label>
                            <input type="text" class="form-control" id="country">
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

Вход в полноэкранный режим Выход из полноэкранного режима

В приведенной выше форме я добавил класс ui-widget в поле адреса улицы, потому что я использую библиотеку jQuery autocomplete для всплытия адреса, возвращаемого google API, когда пользователь начинает вводить адрес в поле адреса улицы. Этот класс включит наше автозаполнение.

Наконец, мы зарегистрируем маршрут в web.php для просмотра нашей формы.

Route::get('/autocomplete',[GoogleAutocompleteController::class,'index']);

Вход в полноэкранный режим Выход из полноэкранного режима

Теперь, когда вы перейдете по ссылке /autocomplete в браузере, вы увидите эту форму

Часть 2
В этой части мы будем использовать библиотеку jQuery autocomplete и API места. Google place API вернет идентификатор места, и на основе этого идентификатора мы заполним все поля формы.

Шаг 1: перейдите к jQuery autocomplete
скопируйте ссылки jquery-ui.js и jquery-ui.css и вставьте их в ваш app.blade.php.

Теперь мой layouts/app.blade.php выглядит следующим образом

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    <link rel="stylesheet" href="//code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    {{ config('app.name', 'Laravel') }}
                </a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav me-auto">

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ms-auto">
                        <!-- Authentication Links -->
                        @guest
                            @if (Route::has('login'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
                                </li>
                            @endif

                            @if (Route::has('register'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
                                </li>
                            @endif
                        @else
                            <li class="nav-item dropdown">
                                <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                    {{ Auth::user()->name }}
                                </a>

                                <div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" href="{{ route('logout') }}"
                                       onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                        {{ __('Logout') }}
                                    </a>

                                    <form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
                                        @csrf
                                    </form>
                                </div>
                            </li>
                        @endguest
                    </ul>
                </div>
            </div>
        </nav>

        <main class="py-4">
            @yield('content')
            @yield('script')
        </main>
    </div>
</body>
</html>

Вход в полноэкранный режим Выход из полноэкранного режима

Как вы можете видеть, я добавил @yield('script') выше, что означает, что все, что я обернул в script, будет инжектировано сюда. Позже мы обернем javascript в @section('script')//..js код @endsection в form.blade.php.

Шаг 2: перейдите к Google Place API
Вы можете увидеть типы, Вы можете ограничить результаты запроса автозаполнения Place определенным типом, передав параметр types. Этот параметр указывает тип или коллекцию типов, как указано в разделе Типы мест. Если ничего не указано, возвращаются все типы.
Нам нужны типы address.

Итак, скопируйте этот URL и откройте ваш почтальон или браузер, вставьте его и нажмите кнопку отправить.

Вы должны получить ответ, подобный этому:

Примечание: нас интересует place_id ответа. Это потому, что с помощью place_id мы можем получить country, street addres, post code, city и т.д.

Шаг 3: Откройте ваш config/services.php и установите ключ

'googlekey'=>[
    'key'=> env('GOOGLE_KEY', null),
 ],
Войти в полноэкранный режим Выйти из полноэкранного режима

и в вашем файле .env.

GOOGLE_KEY=YOUR_GOOGLE_KEY

Шаг 4: Теперь давайте сделаем еще один маршрут в web.php.

Route::get('/placeid',[ GoogleAutocompleteController::class,'getPlaceId'])->name('placeid');
Войти в полноэкранный режим Выйти из полноэкранного режима

и GoogleAutocompleteController.php будет выглядеть следующим образом

<?php

namespace AppHttpControllers;

use IlluminateViewView;
use IlluminateHttpRequest;

class GoogleAutocompleteController extends Controller
{

    public function index(): View
    {
        return view('form');
    }

    public function getPlaceId(Request $request)
    {
        //get user typed address via ajax request
    }

}
Вход в полноэкранный режим Выйти из полноэкранного режима

Шаг 5: В нашем form.blade.php добавим код jQuery для включения выпадающего списка автозаполнения, ajax запрос для отправки введенного пользователем адреса в конечную точку /placeId.

 <script>
        $(document).ready(function() {
            $(".autocomplete-google").autocomplete({
                source: function(request, response) {
                    $.ajax({
                        url: '/placeid',
                        type: 'GET',
                        dataType: "json",
                        data: {
                            inputData: request.term,
                        },
                        success: function(data) {
                            response(data);
                        }
                    });
                },
            });
        });
  </script>

Вход в полноэкранный режим Выход из полноэкранного режима

Теперь наш полный resources/form.blade.php выглядит следующим образом

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Google autocomplete</div>
                    <div class="card-body">
                        <div class="form-group">
                            <label for="streetaddress">Street address</label>
                            <input type="text" class="form-control ui-widget autocomplete-google" id="street_address_1">
                        </div>

                        <div class="form-group">
                            <label for="streetaddress2">Street address 2</label>
                            <input type="text" class="form-control" id="street_address_2">
                        </div>

                        <div class="form-group">
                            <label for="city">City</label>
                            <input type="text" class="form-control" id="city">
                        </div>

                        <div class="form-group">
                            <label for="state">State</label>
                            <input type="text" class="form-control" id="state">
                        </div>

                        <div class="form-group">
                            <label for="postcode">Postcode</label>
                            <input type="text" class="form-control" id="postcode">
                        </div>

                        <div class="form-group">
                            <label for="country">Country</label>
                            <input type="text" class="form-control" id="country">
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

@section('script')
<script>
    $(document).ready(function() {
        $(".autocomplete-google").autocomplete({
            source: function(request, response) {
                $.ajax({
                    url: '/placeid',
                    type: 'GET',
                    dataType: "json",
                    data: {
                        inputData: request.term,
                    },
                    success: function(data) {
                        response(data);
                    }
                });
            },
        });
    });
</script>
@endsection
Вход в полноэкранный режим Выйти из полноэкранного режима

Шаг 6: Теперь давайте создадим специальный класс-обработчик для автозаполнения. Мы могли бы написать весь код в getPlaceId() из GoogleAutocompleteController, но для очистки кода, я думаю, будет хорошей идеей перенести всю логику в другой класс PHP.
Давайте сделаем AutocompleteHandler.php внутри папки Integration в каталоге app.

<?php

namespace AppIntegration;

use GuzzleHttpClient;

class AutocompleteHandler
{

    public const BASE_URL = "https://maps.googleapis.com/maps/api/place";

    public string $key;

    public function __construct()
    {
        $this->key = config('services.googlekey.key');
    }

    public function placeId(string $address)
    {
       //
    }
}

Вход в полноэкранный режим Выйти из полноэкранного режима

В приведенном выше коде я установил базовые URL и key, которые мы будем использовать позже. В приведенном выше методе placeId(string $address) мы получаем адрес в качестве строкового параметра, который мы получим из метода GoogleAutocompleteController getPlaceId(), как показано ниже.

Шаг 7: Теперь внедрим AutocompleteHandler.php в GoogleAutocompleteController.php и передадим адрес из getPlaceId() из GoogleAutocompleteController.php в placeId() из AutocompleteHandler.php.

Теперь наш GoogleAutocompleteController.php выглядит следующим образом

<?php

namespace AppHttpControllers;

use IlluminateViewView;
use IlluminateHttpRequest;
use SymfonyComponentHttpFoundationJsonResponse;
use AppIntegrationAutocompleteHandler;

class GoogleAutocompleteController extends Controller
{

    public $googleAutocomplete;

    public function __construct(AutocompleteHandler $googleAutocomplete)
    {
        $this->googleAutocomplete = $googleAutocomplete;
    }

    public function index(): View
    {
        return view('form');
    }

    public function getPlaceId(Request $request): JsonResponse
    {
        return $this->googleAutocomplete->placeId($request->inputData);
    }

}

Вход в полноэкранный режим Выход из полноэкранного режима

Выше, мы получаем адрес как inputData и передаем этот inputData как address параметр в placeId().

Шаг 8: Теперь давайте поработаем над AutocompleteHandler.php. Здесь я укажу шаги, которые мы будем выполнять

<?php 
namespace AppIntegration;

use GuzzleHttpClient;

class AutocompleteHandler {

    public const BASE_URL = "https://maps.googleapis.com/maps/api/place";
    public string $key;

    public function __construct()
    {
        $this->key = config('services.googlekey.key');
    }

    public function placeId(string $address)
    {

        $url= https://maps.googleapis.com/maps/api/place/autocomplete/json?input=kathmandu&types=address&key=YOUR_API_KEY
// build the readable url with http_build_query and sprintf()

        try {
            // step1: instantiate GuzzleHttp client
            // step2: hit the url
            // step3: get json response
            // step4: convert json to array
            // step5: loop over the predictions array of response
            // step6: and return place_id as id and description as label

        } catch (Exception $e) {
            //catch error
        }
    }

}
Войти в полноэкранный режим Выйти из полноэкранного режима

Итак, наш окончательный вариант AutocompleteHandler.php выглядит следующим образом

<?php

namespace AppIntegration;

use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentHttpFoundationResponse;
use GuzzleHttpClient;

class AutocompleteHandler
{

    public const BASE_URL = "https://maps.googleapis.com/maps/api/place";

    public string $key;
    public function __construct()
    {
        $this->key = config('services.googlekey.key');
    }

    public function placeId(string $address): JsonResponse
    {
        $url = sprintf(
            '%s/autocomplete/json?%s',
            self::BASE_URL,
            http_build_query([
                'input' => $address,
                'types' => 'address',
                'key' => $this->key,
            ])
        );
        try {
            $client = new Client();
            $response = $client->request('get', $url);
            $responseJson = $response->getBody()->getContents();
            $responseArray = json_decode($responseJson, true);
            return response()->json(collect($responseArray['predictions'])->map(
                fn ($value) =>
                [
                    'id' => $value['place_id'],
                    'label' => $value['description'],
                ]
            ));
        } catch (Exception $e) {
            return response()->json([
                'error' => $e->getMessage(),
            ], Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }
}

Вход в полноэкранный режим Выйти из полноэкранного режима

Выше я преобразовал $responseArray в коллекцию с помощью collect() и отобразил его, чтобы вернуть place_id и description.

Теперь, когда вы начнете вводить форму, она начнет предлагать вам адрес, как показано ниже.

Часть 3
Это последняя часть автозаполнения google place. В этой части мы заполним остальные поля формы, когда пользователь выберет один адрес из выпадающего списка.
Теперь нам нужен place_id из предыдущего ответа, и если вы нажмете на этот URL: https://maps.googleapis.com/maps/api/place/details/json?place_id=EhtOZXBhbCBUYXIsIEthdGhtYW5kdSwgTmVwYWwiLiosChQKEgk9yaxKzhjrORHvFQWGXi5RGhIUChIJv6p7MIoZ6zkR6rGN8Rt8E7U&key=YOUR_KEY.
Вы получите ответ в таком формате.

Таким образом, мы получаем результат в виде ответа, а все необходимые данные, такие как адрес, город, почтовый индекс и т.д. находятся в компонентах адреса.

Шаг 1:В приведенном выше примере мы возвращаем place_id в качестве id, и теперь, когда пользователь нажмет на адрес, мы сделаем еще один ajax запрос, чтобы получить все детали места на основе place_id.
Итак, после исходного текста мы можем добавить select, как показано ниже

  select: function(event, ui) {
         var placeId = ui.item.id;
         console.log(placeId)        
   }
Войти в полноэкранный режим Выйти из полноэкранного режима

Таким образом, наш код jQuery выглядит следующим образом

<script>
        $(document).ready(function() {
            $(".autocomplete-google").autocomplete({
                source: function(request, response) {
                    $.ajax({
                        url: '/placeid',
                        type: 'GET',
                        dataType: "json",
                        data: {
                            inputData: request.term,
                        },
                        success: function(data) {
                            response(data);
                        }
                    });
                },
                select: function(event, ui) {
                    var placeId = ui.item.id;
                    console.log(placeId)

                }
            });
        });
 </script>
Вход в полноэкранный режим Выйти из полноэкранного режима

если вы нажмете на выбранный адрес, он вернет идентификатор места в консоль.

Шаг2: давайте сделаем конечную точку, которая будет принимать идентификатор места и возвращать информацию о месте на основе идентификатора места

В web.php

Route::get('address',[ GoogleAutocompleteController::class,'findAddressBasedOnPlaceId'])->name('address');
Войдите в полноэкранный режим Выйти из полноэкранного режима

Итак, теперь web.php выглядит следующим образом

<?php

use IlluminateSupportFacadesRoute;
use AppHttpControllersGoogleAutocompleteController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/autocomplete',[ GoogleAutocompleteController::class,'index']);
Route::get('/placeid',[ GoogleAutocompleteController::class,'getPlaceId'])->name('placeid');
Route::get('address',[ GoogleAutocompleteController::class,'findAddressBasedOnPlaceId'])->name('address');

Auth::routes();

Route::get('/home', [AppHttpControllersHomeController::class, 'index'])->name('home');
Войти в полноэкранный режим Выйти из полноэкранного режима

Шаг2: давайте сделаем этот метод в GoogleAutocompleteController.php

    public function findAddressBasedOnPlaceId(Request $request)
    {
        //get place_id via ajax request when user select the address from dropdown suggestions
    }
Войти в полноэкранный режим Выйти из полноэкранного режима

Шаг3: Из приведенного выше ответа, полученного от API, мы видим, что наши данные находятся в address_components, и все ответы могут возвращать или не возвращать почтовый индекс, название населенного пункта и т.д. для этого place_id. Поэтому нам нужно вручную проверить, присутствуют ли необходимые ключи в ответе или нет, чтобы предотвратить ошибку на странице. Например, если в ответе присутствует почтовый индекс, то мы возвращаем почтовый индекс, и так далее. Поэтому вместо того, чтобы писать оператор if-else для каждого ключа, давайте сделаем вспомогательную функцию, которая возвращает нужный ключ, если он есть в ответе.

Теперь в AutocompleteHandler.php я добавлю следующие проверки

    public function getDataFromAddressComponent(array $addressComponents, string $searchFor): ?string
    {
        return collect($addressComponents)->map(fn ($addressComponent) => collect($addressComponent['types'])->contains($searchFor) ? $addressComponent['long_name'] : null)->filter()->first();
    }
Вход в полноэкранный режим Выйти из полноэкранного режима

Выше я перебираю $addressComponents и проверяю, есть ли у нас $searchFor в этом массиве. Если true, то возвращается что-то, если нет, то возвращается null. Однако здесь я использовал коллекцию.

В качестве альтернативы мы можем сделать следующее

      foreach ($addressComponents as $address) {
            if (in_array($searchFor, $address['types'])) {
                return $address['long_name'];
            }
        }
        return null;

Войти в полноэкранный режим Выйти из полноэкранного режима

Шаг 4: В GoogleAutocompleteController.php мы примем id места из ajax запроса и передадим его в метод addressBasedOnPlaceId() в AutocompleteHandler.php, который вернет детали места

 public function findAddressBasedOnPlaceId(Request $request): JsonResponse
 {
      return $this->googleAutocomplete->addressBasedOnPlaceId($request->placeId);
 }
Вход в полноэкранный режим Выйти из полноэкранного режима

Шаг 5: Отправим идентификатор места в метод findAddressBasedOnPlaceId() через ajax

Мы добавим getAddressDetails(placeId) в

 select: function(event, ui) {
       var placeId = ui.item.id;
        getAddressDetails(placeId);
  }
Вход в полноэкранный режим Выйти из полноэкранного режима

Функция getAddressDetails() сделает ajax запрос к нашей конечной точке /address.
Теперь наш resource/form.blade.php выглядит следующим образом

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Google autocomplete</div>
                    <div class="card-body">
                        <div class="form-group">
                            <label for="streetaddress">Street number</label>
                            <input type="text" class="form-control ui-widget autocomplete-google" id="street_address_1">
                        </div>

                        <div class="form-group">
                            <label for="streetaddress2">Street address 2</label>
                            <input type="text" class="form-control" id="street_address_2">
                        </div>

                        <div class="form-group">
                            <label for="city">City</label>
                            <input type="text" class="form-control" id="city">
                        </div>

                        <div class="form-group">
                            <label for="state">State</label>
                            <input type="text" class="form-control" id="state">
                        </div>

                        <div class="form-group">
                            <label for="postcode">Postcode</label>
                            <input type="text" class="form-control" id="postcode">
                        </div>

                        <div class="form-group">
                            <label for="country">Country</label>
                            <input type="text" class="form-control" id="country">
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

@section('script')
    <script>
        $(document).ready(function() {
            $(".autocomplete-google").autocomplete({
                source: function(request, response) {
                    $.ajax({
                        url: '/placeid',
                        type: 'GET',
                        dataType: "json",
                        data: {
                            inputData: request.term,
                        },
                        success: function(data) {
                            response(data);
                        }
                    });
                },
                select: function(event, ui) {
                    var placeId = ui.item.id;
                    getAddressDetails(placeId);
                }
            });
        });
        function getAddressDetails(placeId) {
        $.ajax({
            url: "/address",
            type: 'GET',
            dataType: "json",
            data: {
                placeId: placeId,
            },
            success: function(data) {
                $('#country').val(data.country);
                $('#city').val(data.locality);
                $('#postcode').val(data.postal_code);
                $('#state').val(data.state);
                $('#street_address_1').val(data.streetNumber);
                $('#street_address_2').val(data.streetName);
            },
            catch: function(error) {
                console.log('error');
            }
        });
    }
    </script>
@endsection
Вход в полноэкранный режим Выход из полноэкранного режима

Выше, при успехе, мы получаем результат и заполняем форму с id страны, города, почтового индекса и штата, хотя наш api не готов возвращать данные о месте на основе id места.

Шаг 6: В AutocompleteHandler.php мы сделаем addressBasedOnPlaceId(), который будет принимать Id места, отправленный из нашего findAddressBasedOnPlaceId() из GoogleAutocompleteController.php.

public function addressBasedOnPlaceId(string $placeId): JsonResponse
{
    $url =   $url = // build the readable url with http_build_query and sprintf()
    https://maps.googleapis.com/maps/api/place/details/json?place_id=EhtOZXBhbCBUYXIsIEthdGhtYW5kdSwgTmVwYWwiLiosChQKEgk9yaxKzhjrORHvFQWGXi5RGhIUChIJv6p7MIoZ6zkR6rGN8Rt8E7U&key=YOUR_KEY
    );
    try {
        // step1: instantiate GuzzleHttp client
        // step2: hit the url
        // step3: get json response
        // step4: convert json to array
        // step5: return required data such as street name, city,postcode, country etc

    } catch (Exception $e) {
        //catch error
    }
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Шаг 7: Окончательный вариант AutocompleteHandler.php выглядит следующим образом

<?php

namespace AppIntegration;

use GuzzleHttpClient;
use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentHttpFoundationResponse;

class AutocompleteHandler
{

    public const BASE_URL = "https://maps.googleapis.com/maps/api/place";

    private $key;
    public function __construct()
    {
        $this->key = config('services.googlekey.key');
    }

    public function getDataFromAddressComponent(array $addressComponents, string $searchFor): ?string
    {
        return collect($addressComponents)->map(fn ($addressComponent) => collect($addressComponent['types'])->contains($searchFor) ? $addressComponent['long_name'] : null)->filter()->first();
    }

    public function placeId(string $address): JsonResponse
    {
        $url = sprintf(
            '%s/autocomplete/json?%s',
            self::BASE_URL,
            http_build_query([
                'input' => $address,
                'types' => 'address',
                'key' => $this->key,
            ])
        );
        try {
            $client = new Client();
            $response = $client->request('get', $url);
            $responseJson = $response->getBody()->getContents();
            $responseArray = json_decode($responseJson, true);

            return response()->json(collect($responseArray['predictions'])->map(
                fn ($value) =>
                [
                    'id' => $value['place_id'],
                    'label' => $value['description'],
                ]
            ));
        } catch (Exception $e) {
            return response()->json([
                'error' => $e->getMessage(),
            ], Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    public function addressBasedOnPlaceId(string $placeId): JsonResponse
    {
        $url = sprintf(
            '%s/details/json?%s',
            self::BASE_URL,
            http_build_query([
                'place_id' => $placeId,
                'key' => $this->key,
            ])
        );
        try {
            $client = new Client();
            $response = $client->request('get', $url);
            $responseJson =  $response->getBody()->getContents();
            $responseArray = json_decode($responseJson, true);

            return response()->json([
                'streetNumber' => $this->getDataFromAddressComponent($responseArray['result']['address_components'], 'street_number'),
                'streetName' => $this->getDataFromAddressComponent($responseArray['result']['address_components'], 'route'),
                'locality' => $this->getDataFromAddressComponent($responseArray['result']['address_components'], 'locality'),
                'state' => $this->getDataFromAddressComponent($responseArray['result']['address_components'], 'administrative_area_level_1'),
                'administrative_area_level_2' => $this->getDataFromAddressComponent($responseArray['result']['address_components'], 'administrative_area_level_2'),
                'country' => $this->getDataFromAddressComponent($responseArray['result']['address_components'], 'country'),
                'postal_code' => $this->getDataFromAddressComponent($responseArray['result']['address_components'], 'postal_code')
            ]);
        } catch (Exception $e) {
            return response()->json(['error' => $e->getMessage(), 'exception' => get_class($e)], Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }
}

Войти в полноэкранный режим Выйти из полноэкранного режима

Итак, мы вернули в ответ StreetNumber, StreetName, locality, state, postcode и country и заполнили этими значениями остальные поля формы.

👉 Получить код

Оцените статью
devanswers.ru
Добавить комментарий