'Livewire lost data when emit event

i'm having a problem when i emit event from javascript to Livewire.

In my mount function i'm storing plan public propertie, when i emit the Livewire.emit('newSubscription', setupIntent.payment_method); event from javascript to my component and i trying to get the plan propertie the value is the model but with empty properties.

Pay.php

class Pay extends Component
{
public $paymentMethod;
public $slug;
public $publicKey;
public $interval;
public $plan;
private $p;
public $payWithNewCard = false;

protected $listeners = ['newSubscription'];

public function mount($slug, $interval)
{
    $this->publicKey = config('cashier.key');
    $this->slug = $slug;
    $this->interval = $interval;

    $user = auth()->user();

    //Check if the user has a subscription
    if ( auth()->user()->subscribed('default') ) {
        return redirect()->route('billing.subscription');
    }

    if ( $interval != 'month' && $interval != 'year' ) {
        return redirect()->route('billing.premium');
    }

    //Get plan
    $this->plan = Product::select('products.slug', 
    'products.trial_period_days', 'prices.currency', 'prices.interval', 
    'products.stripe_product_id as product', 
    'products.name', 'prices.amount', 'products.trial_period_days', 
    'prices.stripe_price_id', 'prices.id as price_id')
    ->where('products.active', '=', '1')
    ->where('prices.active', '=', '1')
    ->where('products.slug', '=', $this->slug)
    ->where('prices.interval', '=', $this->interval)
    ->join('prices', 'products.id', '=', 'prices.product_id')->first();

    dump($this->plan);
    //If plan doesn't exists, redirect to premium
    if ( !$this->plan ) {
        return redirect()->route('billing.premium');
    }
}

public function render()
{
    return view('livewire.billing.pay', [
        'intent' => auth()->user()->createSetupIntent()
    ]);
}

public function newSubscription($paymentMethod)
{
    try {
        //TODO: Validate only trial in first time
        $user = auth()->user();

            //If user has payment method
        if ( $user->hasPaymentMethod() ) {
            $user->addPaymentMethod($paymentMethod);
        } else {
            $user->updateDefaultPaymentMethod($paymentMethod);
        }
        dd($this->plan);
        if ( $this->plan->trial_period_days ) {
            $result = $user
            ->newSubscription('default', $this->plan->price_id)
            ->trialDays($this->plan->trial_period_days)
            ->create(($paymentMethod) ? $paymentMethod : '');
        } else {
            $result = $user
            ->newSubscription('default', $this->plan->price_id)
            ->create(($paymentMethod) ? $paymentMethod : '');
        }
            
            return redirect()->route('billing.success');
        
    } catch ( IncompletePayment $exception ) {
        return redirect()->route(
            'cashier.payment',
            [$exception->payment->id, 'redirect' => route('billing.index')]
        );
    }
}

}

Pay.blade.php

<div class="container" x-cloak x-data="pay()" x-init="mount()">
<div class="mb-4 plan-selected mx-auto px-8 py-4 text-center bg-white rounded-lg shadow">
    <div class="flex justify-between">
        <div class="flex items-center">
            <h3 class="text-2xl font-bold font-heading">{{ $plan->name }}</h3>
        </div>
        <div>
            <span class="flex items-center justify-center text-2xl font-bold text-black font-heading">${{ $plan->amount }}<span class="ml-1 text-xs">{{ $plan->currency }}</span><span class="ml-1 text-xs">/ {{ $plan->interval }}</span></span>
            <div class="text-right flex flex-col">
                <a class="text-xs text-right ml-auto text-blue-500" href="{{ route('billing.premium') }}">Seleccionar otro plan</a>
                @if ( auth()->user()->hasDefaultPaymentMethod() )
                    <span class="text-xs text-right mt-4 ml-auto text-blue-500 cursor-pointer" x-on:click="payWithNewCard = !payWithNewCard">Elegir otro método de pago</span>
                @endif
            </div>
        </div>
        
    </div>
</div>
<div class="mb-4 plan-selected mx-auto px-8 py-4 text-center bg-white rounded-lg shadow">
    @if ( auth()->user()->hasDefaultPaymentMethod() )
        <div x-show="!payWithNewCard" x-transition>
            <!-- If the user has default payment method -->
            <x-button wire:loading.attr="disabled" wire:target="newSubscription" wire:click="newSubscription('{{ $plan->stripe_price_id }}')">
                <x-loading wire:target="newSubscription"></x-loading>
                Pagar con tarjeta terminación {{ auth()->user()->pm_last_four }}
            </x-button>    
        </div>
        <div x-show="payWithNewCard" x-transition>
            <!-- If the user doesn't has payment method, show form to add payment method -->
            <div class="">
                <div class="relative">
                    <form action="" id="card-form">
                        <div class="card-body">
                            <div class="flex space-x-8">
                                <div class="flex-1">
                                    <div>
                                        {{ $paymentMethod }}
                                        <input id="card-holder-name" placeholder="Nombre del títular de la tarjeta" type="text" class="form-control">
                                    </div>
                                    <div >
                                        <!-- Stripe Elements Placeholder -->
                                        <div class="form-control" id="card-element"></div>
                                        <span id="card-error"></span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </form>
                    <div class="card-footer flex flex-col md:flex-row justify-end">
                        <x-button id="card-button" x-on:click="createPaymentMethod()"  data-secret="{{ $intent->client_secret }}">
                            <x-loading></x-loading>
                            Pagar
                        </x-button>
                    </div>
                    <div class="bg-red-700 mt-2 rounded text-white" id="cardErrors">
                    
                    </div>
                </div>
        </div>
            

    @else
        <!-- If the user doesn't has payment method, show form to add payment method -->
        @livewire('billing.payment-method-create', ['buttonText' => 'Pagar', 'name' => $plan->name, 'priceId' => $plan->stripe_price_id])
    @endif    
</div>
@push('scripts')
    <script>
        function pay()
        {
            return {
                payWithNewCard:false,
                stripe:null,
                elements:null,
                cardElement:null,
                cardHolderName:null,
                cardButton:null,
                clientSecret:null,
                mount()
                {
                    this.stripe = Stripe("{{ $publicKey }}");
                    this.elements = this.stripe.elements();
                    this.cardElement = this.elements.create('card');
                    this.cardElement.mount('#card-element');

                    this.cardHolderName = document.getElementById('card-holder-name');
                    this.cardButton = document.getElementById('card-button');
                    this.clientSecret = this.cardButton.dataset.secret;
                },
                async createPaymentMethod ()
                {
                    //TODO: Verify that card doesnt exists, if exists get the id and pass
                    this.payWithNewCard = true;
                    const { setupIntent, error } = await this.stripe.confirmCardSetup(
                        this.clientSecret, {
                            payment_method: {
                                card: this.cardElement,
                                billing_details: { name: this.cardHolderName.value }
                            }
                        }
                    );

                    if (error) {
                        document.getElementById('cardErrors').textContent = error.message;
                    } else {
                        Livewire.emit('newSubscription', setupIntent.payment_method);
                    }
                }
            }
        }
    </script>
@endpush

Image with dump when component is mounted

Image with dump after emit NewSubscriptionEvent



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source