What seems to be the problem:
I am making a simple component to manage tags. There’s an input box - when you type into it, it checks to see if there are any matching tags and generates a dropdown list. You can then select from that list or hit an Add button. The selected tags are then displayed about the input box, each with a button to delete the selection fo that tag. This all works fine for the first tag. As soon as you as you start to type in the input box for the next tag, Livewire crashes with an error referring to the rendering of the selected tag array - Trying to get property ‘name’ of non-object. Nothing in the render() method refers to that array, and it displayed correctly in the previous cycle.
The $selected_tags array is an array of an Eloquent model (super simple - basically only has a name
property plus an id). Adding a new tag or picking a found existing tag works correctly - it shows up above the input box. Type one character into the input box and it crashes.
I’m pretty new at Livewire - sorry for all the code. All help most welcome. Thanks!!
Steps to Reproduce:
see above
Are you using the latest version of Livewire:
yes
Do you have any screenshots or code examples:
Here’s the class file:
class TagInput extends Component
{
public $tag_input; // the search/enter input box
public $found_tags; // tags matching search
public $selected_tags; // collection of Tag objects
public $status;
public function mount()
{
$this->tag_input = '';
$this->selected_tags = [];
$this->found_tags = [];
$this->status = 'nothing';
}
public function render()
{
if (strlen($this->tag_input) > 2) {
$found = Tag::where('name', "like", $this->tag_input . "%")->get();
if ($found) {
//$this->status = "found";
$this->found_tags = $found;
} else {
//$this->status = "not found";
}
} else {
$this->found_tags = [];
}
return view('livewire.tag-input');
}
public function addExistingTag($found_id)
{
if (!in_array($this->found_tags[$found_id]->id, $this->selected_tags)) {
$this->updateTags($this->found_tags[$found_id]);
}
}
public function addNewTag()
{
$new_tag = Tag::create([
'name' => $this->tag_input,
]);
$this->updateTags($new_tag);
}
public function removeTag($tag_id)
{
unset($this->selected_tags[$tag_id]);
$this->selected_tags = array_values($this->selected_tags);
}
private function updateTags(Tag $tag)
{
$this->selected_tags[$tag->id] = $tag;
$this->tag_input = "";
$this->found_tags = [];
}
}
Here’s the blade file (sorry for the crappy Tailwind - still learning):
<div class="mt-3 border-2 text-red-500">{{ $status }}</div>
<div class="flex">
@foreach($selected_tags as $key => $tag)
<div class="flex border-2 border-blue-300 bg-blue-300">
<span class="">{{ $tag->name }}</span>
<button wire:click="removeTag({{ $key }})" class="bg-red-800 text-red-100 m-2">X</button>
</div>
@endforeach
</div>
<div class="flex">
<input type="text" wire:model="tag_input" class="m-3">
<button wire:click="addNewTag">
+
</button>
</div>
<div x-data="{ open: true }" class="relative inline-block text-left">
<div x-show="open" >
<div class="rounded-md bg-white shadow-xs">
@foreach($found_tags as $key => $tag)
<div class="py-1">
<a href="#"
wire:click="addExistingTag({{ $key }})"
>
{{ $tag->name }}
</a>
</div>
<div class="border-t border-gray-100"></div>
@endforeach
</div>
</div>
</div>