floryan's avatar
Level 13

User input breaking computed properties

I have this property:

#[Validate('required', 'int')]
public int $priceDiscount = 0;

which is a component of computed property:

#[Computed]
public function priceFinal(): int
{
    return $this->price + $this->priceDiscount;
}

User can provide negative values of priceDiscount in following input:

<input
    type="number"
    step="25"
    class="form-control form-control-sm"
    style="width: 85px"
    value="25"
    wire:model.live.debounce="priceDiscount"
>

The problem is, if user types just minus sign (-) into the field, which is proper start of negative integer, Livewire sends that sign to the backend and throws an error:

Property [$priceDiscount] not found on component: [calculator]

So my question is, how to prevent Livewire from sending just - or how to set some fallback value of priceDiscount like 0, so if I decided to send that on blur, it just replaces minus sign with 0?

What's the best approach to handle that?

0 likes
1 reply
LaryAI's avatar
Level 58

To handle the issue of Livewire sending just a minus sign to the backend and causing an error, you can use a combination of Livewire's updated lifecycle hook and some validation logic to ensure that the $priceDiscount property is always an integer. Here's how you can do it:

  1. Use the updated lifecycle hook to listen for changes to the priceDiscount property.
  2. Check if the priceDiscount is just a minus sign or not a number, and if so, reset it to 0 or any other default value you prefer.

Here's an example of how you can implement this in your Livewire component:

class Calculator extends Component
{
    #[Validate('required', 'int')]
    public int $priceDiscount = 0;

    public function updated($propertyName)
    {
        if ($propertyName === 'priceDiscount') {
            if ($this->priceDiscount === '-' || !is_numeric($this->priceDiscount)) {
                $this->priceDiscount = 0;
            }
        }
    }

    #[Computed]
    public function priceFinal(): int
    {
        return $this->price + $this->priceDiscount;
    }

    // ... rest of your component
}

In the updated method, we're checking if the updated property is priceDiscount. If it is, we then check if the value is just a minus sign or not a number using is_numeric. If either condition is true, we reset the priceDiscount to 0.

This approach ensures that the priceDiscount property will always be an integer, and it will prevent Livewire from sending invalid values to the backend. Additionally, it will handle the case where a user types a minus sign and then blurs the input field, as the value will be reset to 0.

Remember to import the necessary classes at the top of your Livewire component file:

use Livewire\Component;
use Livewire\WithValidation;

This solution should resolve the issue and provide a better user experience by preventing invalid input from breaking your computed properties.

Please or to participate in this conversation.