I would like to call a function called "syncBudget"
<div wire:key="extendForm" class="card p-3 border-0 shadow-sm space-y-3" x-data="() => {
return {
length: @entangle('length'),
lengthType: @entangle('lengthType'),
coupon: @entangle('coupon'),
partnerPackage: {{ $partnerPackage }},
total: @entangle('total'),
couponDiscount: @entangle('couponDiscount'),
lengthDiscount: @entangle('lengthDiscount'),
amountToPay: @entangle('amountToPay'),
syncBudget: function() {
const coupon = this.coupon;
const data = this.partnerPackage;
let price = data['price']
// Applying length discount
if (this.lengthType == 'monthly') {
this.total = price * this.length;
} else if (this.lengthType == 'yearly') {
this.total = (price * 12) * this.length;
this.lengthDiscount = (this.total / 100) * 10;
}
this.amountToPay = this.total - this.lengthDiscount;
// Applying coupon discount
this.couponDiscount = (this.amountToPay / 100 * coupon['discount']);
this.amountToPay -= this.couponDiscount;
}
}
}">
Need to call it from a livewire function
#[On('apply-coupon')]
public function applyCoupon(Coupon $coupon){
$this->coupon = $coupon->toArray();
$this->dispatch('syncBudget');
}
The flow is, when user apply a coupon. It should dispatch "syncBudget" function. I cant find it in both livewire and alpinejs documentation. Can anyone help me to achieve this one? Thank you
2
Answers
You could do this way inside your apline js component:
I see some things that can be improved here
you don’t need to assign a function to x-data object when defined as HTML attribute, it can be a simple JSON object:
x-data="{ propertyA: null, functionB: function {return null;} }"
your x-data object is quite large so it would be better to define it as external Javascript code (yes, in this case you need to define a function that returns an object)
the AlpineJS code accesses many Livewire properties using @entangle. @entangle is present in Livewire 3 mainly for backwards compatibility since component properties can now be accessed via the $wire object
it seems like you are applying a business-logic in the frontend side: this is not a good practice since anyone can tamper with the code. The business logic should stay in the backend
Note that it is not clear where the $partnerPackage comes from, if it is data passed to the view it should be accessed as
{{ Js::from($partnerPackage) }}
or@json($partnerPackage)
Also it’s not clear why you are assigning a wire:key to your <div>
So, this is your revised code, with the required functionality added:
But I strongly suggest you move the logic to the backend side