javascriptpropertiesundefinedthisalpine.js

In Alpine.JS, this.property inside method is undefined


I have a request for help with Alpine.JS

I have a packetaApiKey property defined. When I access it this.packetaApiKey in the pickPoint method, it works as expected. But in the showSelectedPickupPoint method, this.packetaApiKey returns undefined. With hardcoding the code works fine.

<div>
    <div x-data="packetaWidget()">
        <x-button type="button" x-on:click="pickPoint()">Select point</x-button>
    </div>

    <script>
        function packetaWidget() {
            return {
                packetaApiKey: '{{ $packetaApiKey }}',
                packetaOptions: {
                    country: "sk",
                    language: "sk",
                    valueFormat: "\"Packeta\",id,carrierId,carrierPickupPointId,name,city,street",
                    view: "modal"
                },

                async showSelectedPickupPoint(point) {
                    if (point) {
                        try {
                            const res = await fetch('https://widget.packeta.com/v6/api/pps/api/widget/v1/validate', {
                                method: 'POST',
                                headers: {
                                    'content-type': 'application/json'
                                },
                                body: JSON.stringify({
                                    apiKey: this.packetaApiKey, // this.packetaApiKey is undefined 
                                    point: {
                                        id: point.id,
                                    },
                                }),
                            })

                            if (!res.ok) throw new Error(res.statusText)

                            @this.set('selectedPickupPoint', await res.json())
                        } catch (err) {
                            console.error(err)
                        }
                    }
                },

                pickPoint() {
                    Packeta.Widget.pick(this.packetaApiKey, this.showSelectedPickupPoint, this.packetaOptions)
                }
            }
        }
    </script>
</div>

@assets
    <script src="https://widget.packeta.com/v6/www/js/library.js" defer></script>
@endassets

Thanks for help!

I tried looking for a solution on the internet, rewriting the code, but the result was still undefined.


Solution

  • The function showSelectedPickupPoint() is called from a different context as a callback, so the local packetaApiKey property is not available. You can verify this thing adding a console.log:

    async showSelectedPickupPoint(point) { 
    
        console.log("CONTEXT:", this);
    
        .....
    

    You will see that this is window, not your object.

    Since it seems that the property $packetaApiKey comes from a Livewire class, you can access to it on the frontend side using the global Livewire object, via the @this helper which references the current component:

    body: JSON.stringify({
    
       apiKey: @this.packetaApiKey,
    
       point: {
          id: point.id,
       },
    }),
    

    The local packetaApiKey property can perhaps be removed