janmoes's avatar

Livewire Search component.

Hey there guys! First time i've been actually using Livewire. I've made a simple search query component and it works. But i was just wondering, am I handling it the right way?

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Product;

class ProductSearch extends Component
{
    public $product;
    public $search;

    public function searchProduct(){
        $this->product = Product::find($this->search);
        // dd($this->product);
    }

    public function render()
    {
        // $this->product = Product::find($this->search);
        return view('livewire.product-search');
    }
}

And the rendered blade view:

<div>
    <form wire:submit.prevent="searchProduct">
        <input type="text" wire:model.defer="search">
        <button type="submit" wire:click="searchProduct">Search item</button>
    </form>
    @if(isset($product))
    <p>{{$product->name}}</p>
    @else
    <p>No data to be shown</p>
    @endif
</div>

I was just curious because now, when $product doesn't have a value, or the $product does not exist or whatsoever, i want it to display 'product not found' and i was wondering how i could do that check with eloquent.

0 likes
3 replies
chaudigv's avatar

You can use findOrFail()

use Illuminate\Database\Eloquent\ModelNotFoundException;

public $error = '';

try {
    $this->product = Product::findOrFail($this->search);
    $this->reset(['error']); // set $error to default i.e. ''
} catch(ModelNotFoundException $e) {
    $this->error = 'Product not found.'; // your message when not product found.
}

In your blade

@if(!empty($error))
    {{ $error }}
@endif
janmoes's avatar

Will ModelNotFoundException give me a 404 page or just the $error message you set?

janmoes's avatar

@chaudigv I've modified my code with the addition of yours.

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Product;
use Illuminate\Database\Eloquent\ModelNotFoundException;

class ProductSearch extends Component
{
    public $product;
    public $search;
    public $error = '';

    public function searchProduct(){
        try {
            $this->product = Product::where('name', 'like', '%'.$this->search.'%')->first();
            $this->reset(['error']); // set $error to default i.e. ''
        } catch(ModelNotFoundException $e) {
            $this->error = 'Product not found.'; // your message when not product found.
        }
    }

    public function render()
    {
        // $this->product = Product::find($this->search);
        return view('livewire.product-search');
    }
}
<div>
    <form wire:submit.prevent="searchProduct">
        <input type="text" wire:model.defer="search">
        <button type="submit" >Search item</button>
    </form>
    @if(isset($product))
    <p>{{$product->name}}</p>
    @elseif(isset($error))
    <p>Product not found</p>
    @else
    <p>No data to be shown</p>
    @endif
</div>

So for example, the first time when you load the page, it says 'no data to be shown', after you search something and it found something it says the name of the product. And when you look for something that's not in the database you get the error. So it works correctly right, that the no data to be shown only appears at the beginning because the search method hasn't been execute yet?

Please or to participate in this conversation.