platform icon indicating copy to clipboard operation
platform copied to clipboard

Better Turbo documentation or disabling from project

Open AlejandroAkbal opened this issue 3 years ago • 1 comments

Is your feature request related to a problem? Please describe.

I'm trying to use some Google Maps APIs, using their JavaScript libraries, like so:

@push('scripts')
    <script
        src="https://maps.googleapis.com/maps/api/js?key={{ config('services.google_maps.places_api_key') }}&libraries=places"
        async
        defer
    ></script>

    <script defer>
        document.addEventListener("turbo:load", () => {

            const INPUT_ELEMENT = document.getElementById('google-maps-place-search-input');
            const PLACE_ID_ELEMENT = document.getElementById('google-maps-place-search-place-id');
            const PLACE_NAME_ELEMENT = document.getElementById('google-maps-place-search-place-name');

            function initAutocomplete() {

                const OPTIONS = {
                    fields: ["place_id", "name"],
                };

                const AUTOCOMPLETE = new window.google.maps.places.Autocomplete(INPUT_ELEMENT, OPTIONS);

                AUTOCOMPLETE.addListener("place_changed", () => {
                    const PLACE = AUTOCOMPLETE.getPlace();

                    console.log(PLACE);

                    PLACE_ID_ELEMENT.value = PLACE.place_id;
                    PLACE_NAME_ELEMENT.value = PLACE.name;
                })
            }

            initAutocomplete()
        })
    </script>
@endpush

But this fails. Whenever the page is loaded by navigating from another page, the script errors out. It only works when reloading the same page. I've been readings tons of problems and solutions and still find myself with this problem.

This is the console log:

weather:555 Uncaught TypeError: Cannot read properties of undefined (reading 'maps')
    at initAutocomplete (weather:555:56)
    at HTMLDocument.<anonymous> (weather:570:13)
    at D (orchid.js?id=0f024a0931f58280d2d5a9f80f07edae:2:37326)
    at Object.notifyApplicationAfterPageLoad (orchid.js?id=0f024a0931f58280d2d5a9f80f07edae:16:31143)
    at Object.pageBecameInteractive (orchid.js?id=0f024a0931f58280d2d5a9f80f07edae:16:29493)
    at ie.pageIsInteractive (orchid.js?id=0f024a0931f58280d2d5a9f80f07edae:16:20150)
    at HTMLDocument.interpretReadyState (orchid.js?id=0f024a0931f58280d2d5a9f80f07edae:16:19553)
initAutocomplete @ weather:555
(anonymous) @ weather:570
D @ orchid.js?id=0f024a0931f58280d2d5a9f80f07edae:2
notifyApplicationAfterPageLoad @ orchid.js?id=0f024a0931f58280d2d5a9f80f07edae:16
pageBecameInteractive @ orchid.js?id=0f024a0931f58280d2d5a9f80f07edae:16
pageIsInteractive @ orchid.js?id=0f024a0931f58280d2d5a9f80f07edae:16
interpretReadyState @ orchid.js?id=0f024a0931f58280d2d5a9f80f07edae:16

Describe the solution you'd like

I would like examples of how to make third party scripts work with Turbo. Or a way to completely disable Turbo and Stimulus from the project.

Describe alternatives you've considered

I've tried disabling turbo but I cant modify the blade layout. I've tried removing the listeners from the scripts but has not worked.

AlejandroAkbal avatar Apr 27 '22 11:04 AlejandroAkbal

Hey @AlejandroAkbal Unfortunately, this is not enough for me to reproduce, because there are no fields that your code refers to.

I looked at the maps documentation their documentation is quite complete with good examples: https://developers.google.com/maps/documentation/javascript/overview#js_api_loader_package And I don't see any reason to ignore it and easily match what https://orchid.software/en/docs/javascript/ says in the controller uses

The @googlemaps/js-api-loader package is available to make a more seamless dynamic loading experience. It can be installed through NPM with the following:

npm install @googlemaps/js-api-loader

This package can be imported into the application with:

//maps_controller
import { Loader } from "@googlemaps/js-api-loader"

export default class extends window.Controller {

    connect() {
        const loader = new Loader({
          apiKey: "YOUR_API_KEY",
          version: "weekly",
          ...additionalOptions,
        });
        
        loader.load().then(() => {
          map = new google.maps.Map(this.element.querySelector('.google-maps'), {
            center: { lat: -34.397, lng: 150.644 },
            zoom: 8,
          });
        });
    }
}

And the HTML would look like this:

<div data-controller="maps">
   <div class="google-maps"></div>
</div>

tabuna avatar May 02 '22 14:05 tabuna