Filtering Products according to price filter (from to)

I’m trying to filter my products according to price, using a form in the view, I’m passing from and to as two separate filters and stuck from there.
here’s the code in my Product Model:

public function scopeFilter($query, array $filters)
{
   
    $query->when(
        $filters['from'] ?? false,
        function ($query,$request) {
            $query->whereBetween('price', [$request->from,$request->to]);
        }
    );
}

obviously this isn’t working and when I dd the request it’s giving me the “from” value only.
any ideas??
this is my product controller:
public function index()
{        
    $categories = Category::get();
    $products = Product::latest()->filter(request(['category','from','to']))->simplePaginate(5);

    return view('welcome',compact('products','categories',));
}

at the moment it’s giving me an error of “Trying to get property ‘to’ of non-object”

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You are reading the request wrong, Your scope filter function should be like:

public function scopeFilter($query, array $filters)
    {
        $query->when(
            ($filters['from'] && $filters['to']) ?? false,
            function ($query) use ($filters){
                $query->whereBetween('price', [$filters['from'],$filters['to']]);
            }
        );
    }

Method 2

At the minute, you’re just passing the from price to the closure.
When you use when(), the first argument is passed as the second param of the closure (in this case the from price…false won’t trigger the closure).

You can either add a use statement to the closure:

public function scopeFilter($query, array $filters)
{
    $query->when(
        $filters['from'] ?? false,
        function ($query) use ($filters) {
            $query->whereBetween('price', [$filters['from'], $filters['to']]);
        }
    );
}

or, if you’re using php >= 7.4, you can use an arrow function instead:
public function scopeFilter($query, array $filters)
{
    $query->when(
        $filters['from'] ?? false,
        fn ($query) => $query->whereBetween('price', [$filters['from'], $filters['to']]);
    );
}

Furthermore, it would probably make more sense to remove the when entirely as you should really be validating the values in your controller.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x