How to use when() method in Laravel Eloquent Queries or Collection

How to use when() method in Laravel Eloquent Queries or Collection

Demonstrate how to conditionally add query constraints using when() for cleaner queries or collection

Introduction

In this article i’ll show you how to use when() method in a Laravel application as an alternative to the typical/traditional conditional (if-else) statements/blocks in PHP.

Typical if-else use case

        $query = Post::query();

        if ($request->title == 'Laravel Eloquent Queries') {
            $query->where('title', $request->title);
        }
        $posts = $query->latest()->get();

What is when() method?

The when() method in Laravel is an easy way to apply condition to a query or collection to determine what block of code to execute when the condition evaluates to be true without having to use complex if-else conditional statements or blocks.

💡
You can watch how to How to use when() method in Laravel Eloquent Queries or Collection on my Youtube channel

when() method syntax

$query->when($request->has('title'), function ($query) use ($request) {
    return $query->where('title', $request->title);
});

Breakdown of when() syntax

  • condition: the first argument of the when() syntax as shown in the code above $request->has('title') is the condition which will evaluated to return a boolean value. If the name is present on the request it automatically executes the code of block else it skips the code of block.

  • Callback: the callback closure executes if the condition is satisfied to be true or false as defined by the developer. For example !$request->has('title') simply checks if the name is not available on the request and proceeds which is different from checking if it exist $request->has('title').

  • Optional Callback: An optional callback can be defined to be executed if the first condition is not satisfied.

💡
The unless method is the inverse of when() method

when() method in Action

💡
The first argument (conditions) in when() method can be from a request or a constant variable value defined within the application.
  • Execute the callback if the request has an active parameter and is holds a true value
//return posts with status of true
        $posts = Post::when($request->has('active'), function ($query) {
            return $query->where('status', true);
        })->get();

  • Execute the callback if the request does not have an active variable and is false
$posts = Post::when($request->has('active'), function ($query) {
            return $query->where('status', true);
        }, function ($query) {
            return $query->where('status', false);
        })->get();
💡
Execute the optional callback with false status if the request does not have an active parameter

  • How to use multiple when() method
💡
Kindly ensure to validate values from request parameters
  $validator = Validator::make($request->all(), [
        'title' => 'nullable|string|max:10',
        'content' => 'nullable|string|max:10',
    ]);
    // Check if validation fails
    if ($validator->fails()) {
//         return validation errors 
    }
 $posts = Post::when($request->has('title'), function ($query) use ($request) {
            return $query->where('title', 'LIKE', "%{$request->title}%");
        })->when($request->has('content'), function ($query) use ($request) {
            return $query->where('content', 'LIKE', "%{$request->content}%");
        })->get();

whenEmpty()

        $posts = Post::when($request->has('active'), function ($query) {
            return $query->where('status', true);
        })->get()
        ->whenEmpty(function () {
            //this section will be executed if the posts result is empty
            //You could return a default array
            // return ;
        });

whenNotEmpty()

For example: Let’s assume you want to apply the first letter uppercase transformation to the title column when the posts collection is not empty.

Probably you want to take care of the modification within the controller method without having to do {{ ucwords($post->title) }} in the blade file. There could be more advanced reasons to do this other than just applying uppercase function.

        $posts = Post::when($request->has('active'), function ($query) {
            return $query->where('status', true);
        }, function ($query) {
            return $query->where('status', false);
        })
            ->get()
            ->whenNotEmpty(function ($items) {
                return $items->map(function ($item) {
                    $item->title = ucwords($item->title);
                    return $item;
                });
            });
  • Apply first letter uppercase whenNotEmpty()

💡
when(), whenEmpty(), whenNotEmpty() can be chained together depending on the functionality of the query to be performed.

Conclusion

The application of Laravel when() method in Eloquent queries or collection allows you to apply conditions without using typical conditional if-else statements. This makes the code simple, particularly when filtering data, making it cleaner and more readable. You can chain multiple when() methods to handle for different conditions at a go. However, it's important to carefully review the first argument that contains custom conditions, as the callback will be executed if the condition evaluates to be true.

If you find this article useful please kindly share it with your network and feel free to use the comment section for questions, answers, and contributions.

💡
Follow me on Hashnode: Alemsbaja --- X: Alemsbaja ---- Youtube: Tech with Alemsbaja to stay updated on more articles

Did you find this article valuable?

Support Alemoh Rapheal Baja by becoming a sponsor. Any amount is appreciated!