'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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
