In case somebody bumps into this issue (of whom there many in the cyberspace), I solved it. I think this was the key (I use Breeze), and after that npm run build: https://livewire.laravel.com/docs/troubleshooting#removing-laravel-breezes-alpine And don't worry if you use Alpine plugins, they all are automatically loaded, so remove them too (I use Focus). I found the tip of the skein with the error in console: Detected multiple instances of Alpine running. Happy coding!
Livewire variable not being showed in the input in the view
Hi to all! I have a project in Laravel 11 and Livewire 3. I have Purchase (Compras) Component, which renders two views (Purchases and their lines). I can save the model to the database, the connection from the view to the componeont works. But, the input texts don't show back the updated value of the variables. I know the value comes back from the component because when I debug with Xdebug, the variable has a new value, but the input stays blank, or with the value I assigned at mount(). I put here only the inputs in question (for clarity). The view is enclosed in a div, and, I repeat, the connection works, the updatedFoo() method works. Thanks in advance for any clue you can give. I have spent 30 hours in this, to no avail.
Inputs:
<div class="col-lg-1">
<div class="form-group">
<label class="form-label">Monto:</label>
<input type="number" wire:model="monto" class="form-control" readonly>
@error('monto')
<span class="form-text text-danger">
<i class="icon-cancel-circle2 mr-2"></i>
{{ $message }}
</span>
@enderror
</div>
</div>
<td class="celda">
<input type="number" class="form-control form-control-sm"
wire:model.live="lineas.{{ $index }}.total" readonly>
<div>
@error('lineas.{{ $index }}.total')
{{ $message }}
@enderror
</div>
</td>
The component:
<?php
namespace App\Livewire;
use App\Models\Rubro;
use App\Models\Compra;
use App\Models\Precio;
use App\Models\Potrero;
use Livewire\Component;
use App\Models\Producto;
use App\Models\Proveedor;
use Livewire\WithPagination;
use Livewire\Attributes\Validate;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
class CrearCompras extends Component
{
use WithPagination;
protected $paginationTheme = 'bootstrap';
public Collection $estancias; //las variables de acá son automáticamente pasadas a la vista blade
public Collection $potreros;
public Collection $rubros;
public Collection $proveedors;
#[Validate('required')]
public $fecha = '';
#[Validate('required')]
public $proveedor = '';
#[Validate('required')]
public $vencimiento = '';
public $estanciaElegida = '';
public $potreroElegido = '';
public $factura = '';
#[Validate('required')]
public $tipo = '';
#[Validate('required')]
public $moneda = '';
#[Validate('required')]
public $monto = '';
public $notas = '';
/* public $concepto = ''; */
#[Validate('required')]
public $division = '';
#[Validate('required')]
public $rubro = '';
public $potreroObjeto = '';
/*Sección línea compra*/
public Collection $rubrosLineas;
public Collection $productos;
public $lineas = [];
protected $rules = [
'lineas' => 'required|array|min:1',
'lineas.*.producto_id' => 'required|gt:0',
'lineas.*.cantidad' => 'required|gt:0',
'lineas.*.unitario' => 'required|gt:0',
'lineas.*.descuento' => 'required',
'lineas.*.iva' => 'required|',
'lineas.*.rubro' => 'required|',
'lineas.*.division' => 'required',
];
public function mount()
{
$this->fecha = now('GMT-3')->format('Y-m-d');
$this->vencimiento = now('GMT-3')->addDays(30)->format('Y-m-d');
$this->estancias = Auth::user()->empresa->estancias;
$this->potreros = collect(); //Esto hace que se transforme en una variable de tipo collection
$this->rubros = Rubro::where('empresa_id', Auth::user()->empresa_id)->get();
$this->proveedors = Proveedor::where('empresa_id', Auth::user()->empresa_id)->get();
/*Sección líneas compras*/
$this->productos = Producto::where('empresa_id', Auth::user()->empresa_id)->get();
$this->rubrosLineas = Rubro::where('empresa_id', Auth::user()->empresa_id)->get();
//Hay que hacerlo con arrays porque Livewire no acepta conexiones wire:model a colecciones.
//Y el número asignado, en caso de combos, no es el valor, sino el índice de los elementos del combo,
//salvo en el IVA, no sé por qué. Quizás porque no es foreach
$this->lineas = [
[
'producto_id' => 1,
'cantidad' => 1,
'unitario' => 1,
'iva' => 0,
'descuento' => 1,
'total' => 1,
'rubro' => 2,
'division' => 2,
]
];
}
/*Sección líneas compras*/
public function updatedLineas($value, $key)
{
$campo = explode(".", $key)[1];
if (in_array($campo, ['producto_id', 'cantidad', 'unitario', 'iva', 'descuento'])) {
$this->calcular();
}
}
public function updatedTotal()
{
$i = 8;
}
private function calcular()
//$key y $value DEBEN llamarse así, si no, no anda.
{
foreach ($this->lineas as $key => $value) {
$total = $this->lineas[$key]['cantidad'] *
$this->lineas[$key]['unitario'] *
(1 - ($this->lineas[$key]['descuento'] / 100)) *
(1 + ($this->lineas[$key]['iva'] / 100));
$this->lineas[$key]['total'] = $total;
$this->monto = $total;
}
}
/*Fin sección líneas*/
public function save()
{
//Esto lo hago porque Livewire no detecta el elemento seleccionado por defecto
($this->tipo === "") ? $this->tipo = "Contado" : '';
($this->moneda === "") ? $this->moneda = "Dólares" : '';
$this->validate();
$dolarUltimo = Precio::dolarUltimo($this->fecha);
if ($dolarUltimo === 0) {
$dolarUltimo = session('dolar');
}
$montoUsd = 0;
if ($this->moneda === "Pesos") {
$montoUsd = round($this->monto / $dolarUltimo, 2);
} else {
$montoUsd = $this->monto;
}
if ($this->estanciaElegida === "") {
$this->estanciaElegida = 0;
}
if ($this->potreroElegido === "") {
$this->potreroElegido = 0;
}
$compra = compra::create([
'fecha' => $this->fecha,
'proveedor_id' => $this->proveedor,
'vencimiento' => $this->vencimiento,
'estancia_id' => $this->estanciaElegida,
'potrero_id' => $this->potreroElegido,
'factura' => $this->factura,
'tipo' => $this->tipo,
'moneda' => $this->moneda,
'cambio' => $dolarUltimo,
'monto' => $this->monto,
'monto_usd' => $montoUsd,
'division' => $this->division,
'rubro_id' => $this->rubro,
'creador_id' => auth()->id(),
'empresa_id' => Auth::user()->empresa->id,
'notas' => $this->notas,
]);
return to_route('compras.index')->with('MessageOK', 'compra guardado exitosamente');
}
public function updatedEstanciaElegida($value) //Cuando elige estancia, se actualiza la variable
//enlazada, y automáticamente busca los potreros de esa estancia
{
$this->potreros = Potrero::where('estancia_id', $value)->get();
if ($this->potreros->count() > 0) {
$this->potreroElegido = $this->potreros->first()->id; //Esta línea es para que elija
//uno por defecto, si no, HTML elige el primer elemento del select,pero Livewire no se da cuenta y da error
$this->potreroObjeto = $this->potreros->first();
}
}
public function render()
{
return view('livewire.crear-compras');
}
}
Please or to participate in this conversation.