0
votes

I'm new to Livewire and I encounter an error which origin I don't know.

I made a page with a list of simple objects (id, name, and description). The page has a list of all the items available and I want to click on that list to view the item properties or a button to delete the item.

That list is made with this foreach:

@foreach($listaTareas as $t)
  <div class="data col-12" wire:click="show({{ $t->id }})">
    <label>{{ $t->nombre }}</label>
    <label class="hint">ID: {{ $t->id }}</label>
    <button type="button" class="btn btn-danger" wire:click="delete({{ $t->id }})"><i class="fas fa-trash"></i></button>
  </div>
@endforeach

Which renders perfectly

List rendered

However, clicking on any div or in the trash can button results in error Trying to get property 'id' of non-object pointing at <div class="data col-12" wire:click="show({{ $t->id }})">.

If I delete the show and delete attributes (and modify the livewire component consequentely) leaving something like this:

@foreach($listaTareas as $t)
  <div class="data col-12" wire:click="show">
    <label>{{ $t->nombre }}</label>
    <label class="hint">ID: {{ $t->id }}</label>
    <button type="button" class="btn btn-danger" wire:click="delete"><i class="fas fa-trash"></i></button>
  </div>
@endforeach

I still get the same error, this time pointing at <label>{{ $t->nombre }}</label>, so crearly there is something obvious I'm doing incredibly wrong. I have heard about the wire:key attribute but I don't know how to use it for my purposes.

All the code:

Livewire view

<div class="row align-items-start">
    <!-- Sección de la lista de tareas -->
    <div class="col-5">
        <div id="listado" class="contenedor-data">

            <div id="add">
                <label for="btnadd" class="info">Puedes añadir una tarea con este botón...</label>
                <button id="btnadd" type="button" class="btn btn-primary" wire:click="create">Añadir</button>
            </div>

            @foreach($listaTareas as $t)
                <div class="data col-12" wire:click="show({{ $t->id }})">
                    <label>{{ $t->nombre }}</label>
                    <label class="hint">ID: {{ $t->id }}</label>
                    <button type="button" class="btn btn-danger" wire:click="delete({{ $t->id }})"><i class="fas fa-trash"></i></button>
                </div>
            @endforeach
        
            <div id="coletilla">
                <a class="btn btn-primary" href="#add" role="button">&nbsp;<i class="fas fa-angle-up"></i>&nbsp;</a>
            </div>

        </div>
    </div>
    <!-- Sección del desglose de tareas -->
    <div class="col-7">
        <div id="desglose" class="contenedor-data">

            <div class="form-group">
                <label for="nombre">Tarea:</label>
                <label id="id_tarea" class="hint">{{ $tid }}</label>
                <input type="text" class="form-control" id="nombre" placeholder="Nombre de la tarea" wire:model="nombre">
            </div>
            
            <div class="form-group">
                <label for="descripcion">Descripción</label>
                <textarea class="form-control" id="descripcion" aria-describedby="hint" wire:model="descripcion"></textarea>
                <small id="hint" class="form-text text-muted">Aquí va la descripción de la tarea.</small>
            </div>
            
            <div>
                <button id="btnadd" type="button" class="btn btn-success" wire:click="create">Añadir</button>
                <button id="btnmod" type="button" class="btn btn-primary">Modificar</button>
                <button id="btndel" type="button" class="btn btn-danger">Eliminar</button>
            </div>

        </div>
    </div>
</div>

Livewire Component

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Tarea;

class Index extends Component
{

    // Atributos de tareas
    public $tid;
    public $nombre;
    public $descripcion;

    // Listado tareas
    public $listaTareas = array();

    public function create() {
        $tarea = new Tarea;

        $tarea->nombre = $this->nombre;
        $tarea->descripcion = $this->descripcion;

        if ($tarea->save()) {
            $this->tid = 'ID: '.$tarea->id;
        }

    }

    public function show($id) {
        /* Just to try if it works */
        $this->descripcion = "Show $id";
    }

    public function delete() {
        /* Just to try if it works */
        $this->descripcion = "Delete $id";
    }

    private function rellenarTareas() {
        $tareas = Tarea::get();

        foreach($tareas as $tarea) {
            $this->listaTareas[] = $tarea;
        }
    }

    public function mount()
    {
        // Rellenamos la lista con las tareas que ya existen
        $this->rellenarTareas();
    }

    public function render()
    {
        return view('livewire.index');
    }
}
1
listaTareas has at least (1) element in the array that is not an object which is resulting in this error. Can you dump listaTareas and see it's value?Ohgodwhy
@Ohgodwhy Yes, here is the dump: array:3 [▼ 0 => App\Models\Tarea {#365 ▶} 1 => App\Models\Tarea {#380 ▶} 2 => App\Models\Tarea {#381 ▶} ] What is bugging me is there is no error with listaTareas loading de page, the foreach works fine. The error comes when click on an element of the list. What I'm trying to do is use the show and delete just as a normal functions, but even if I remove the id parameter from them the error still happens, pointing at $t->nombre, so I have no idea the reason this is happeningAsu Suárez

1 Answers

0
votes

I resolved my problem. It was as simple as tricky. In rellenarTareas(), called by mount(), I was getting the Tarea objects from the database and inserting them into an array

private function rellenarTareas() {
    $tareas = Tarea::get();

    foreach($tareas as $tarea) {
        $this->listaTareas[] = $tarea;
    }
}

Debugging the data with dd() showed this:

array:3 [▼
  0 => App\Models\Tarea {#365 ▶}
  1 => App\Models\Tarea {#367 ▶}
  2 => App\Models\Tarea {#381 ▶}
]

I changed the way the array $listaTareas was being filled by directly storing the Tareas::get() into $listaTareas (btw I renamed $listaTareas to $tareas):

private function rellenarTareas() {
    $this->tareas = Tarea::get();
}

Debugging the data with dd() showed this:

Illuminate\Database\Eloquent\Collection {#364 ▼
  #items: array:3 [▼
    0 => App\Models\Tarea {#365 ▶}
    1 => App\Models\Tarea {#367 ▶}
    2 => App\Models\Tarea {#381 ▶}
  ]
}

I have no idea why this solved the issue, but it does. I hope this helps to any newbie like me in Livewire or Laravel.