Calling Alpine.js methods from third-party scripts

gauravmak

Gaurav Makhecha

Posted on March 8, 2022

Calling Alpine.js methods from third-party scripts

How we made Alpine-powered page understand Google Map events

Recently, we faced a small challenge when implementing Google Map on an Alpine.js powered page. Key points:

  • Map markers data is loaded in the Alpine.js store
  • The Google Map is outside the Alpine.js scope so cannot call Alpine method directly after its loaded

There was no way we could show those map markers on the Google Map.

After some surfing, this thread gave a hint. Let us go through the actual code to set up the base.

Google Maps related code

<div class="container">
    <div id="google-map" style="height: 600px;"></div>
</div>

...

<script async src="https://maps.googleapis.com/maps/api/js?key=APIKEY&callback=renderMap"></script>

<script>
    var googleMapObject;

    function renderMap() {
        googleMapObject = new google.maps.Map(document.getElementById("google-map"), {
            // Map config
        });
    }
</script>
Enter fullscreen mode Exit fullscreen mode

And here's the Alpine.js setup code

<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.store('app', {
            mapMarkers: [
                // Pre-loaded markers data
            ]
        });
    });
</script>
Enter fullscreen mode Exit fullscreen mode

Solution

Events to the rescue. You can just fire a custom Javascript window event from the Google Maps object and make Alpine listen to it. Let's see the code:

<script>
    function renderMap() {
        // initialize map code

        var mapLoadedEvent = new Event('map-loaded');
        window.dispatchEvent(mapLoadedEvent);
    }
</script>
Enter fullscreen mode Exit fullscreen mode

First, we are firing the custom JS event called map-loaded once the Google Map is loaded.

<div class="container" x-data @map-loaded.window="$store.app.addAllMarkers()">
    <div id="google-map" style="height: 600px;"></div>
</div>
Enter fullscreen mode Exit fullscreen mode

This HTML code listens to that event and calls the addAllMarkers Alpine method. With that, our Google Map can call the Alpine.js method to show the map markers.

Lastly, our Alpine method can do the rest.

<script>
    var googleMapObject;

    document.addEventListener('alpine:init', () => {
        Alpine.store('app', {
            mapMarkers: [
                // Pre-loaded markers data
            ],

            addAllMarkers() {
                this.mapMarkers.forEach(function (mapMarker) {
                    new google.maps.Marker({
                        // Map marker config
                    });
                });
            },
        });
    });
</script>
Enter fullscreen mode Exit fullscreen mode

We did this for Google Maps but you can do the same with any other third-party JS library using the custom Javascript window event.

Important to Note that a CustomEvent is different from a regular JS Event. Check this Stackoverflow answer for details.

Cheers!

💖 💪 🙅 🚩
gauravmak
Gaurav Makhecha

Posted on March 8, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related