Add Logic to Laravel Requests Conditionally with the when() Method

Photo by Andrew Neel on Unsplash

Add Logic to Laravel Requests Conditionally with the when() Method

Enhance Laravel Requests Conditionally via the when() Method

With the release of Laravel 11.35.0, the Request class now uses the powerful Conditionable trait, bringing the flexibility of the when() and unless() methods to request handling. These methods allow you to write cleaner and more expressive code by conditionally applying logic without cluttering your controllers or request classes with repetitive if statements.

In this blog post, we’ll explore how to leverage these methods to add conditional logic to your Laravel requests and streamline your codebase.

The when() method applies a callback when the given condition resolves to a truthy value. Additionally, you can pass a "default" callback to handle cases where the condition is false.

public function when($value = null, ?callable $callback = null, ?callable $default = null);
  • $value: The condition to evaluate (e.g., a request input value).

  • $callback: Executed if the condition is truthy.

  • $default: Executed if the condition is false.

This method is highly versatile and simplifies request handling in Laravel applications.


The when() method executes a callback if a given condition evaluates to true. Let’s look at some practical examples.

Imagine you’re creating a user and need to assign roles based on the presence of an is_admin flag in the request. Here’s how you can handle this:

public function store(Request $request)
{
    $request->when($request->has('is_admin'), function ($request) {
        // Assign the admin role
        $request->merge(['role' => 'admin']);
    }, function ($request) {
        // Assign the user role
        $request->merge(['role' => 'user']);
    });

    // Save the data
    User::create($request->all());

    return response()->json(['message' => 'User created successfully!']);
}

In this example, the when() method ensures that the role field is conditionally added to the request data based on the presence of is_admin. The default callback simplifies handling cases where the condition is false.


The unless() method is the inverse of when() — it executes a callback if the condition evaluates to false.

Let’s say you want to set a default value for email_verified_at if it’s not provided in the request:

public function update(Request $request, User $user)
{
    $request->unless($request->has('email_verified_at'), function ($request) {
        $request->merge(['email_verified_at' => now()]);
    });

    $user->update($request->all());

    return response()->json(['message' => 'User updated successfully!']);
}

Here, the unless() method simplifies the logic for handling default values.


You can use when() in custom request classes to add validation rules dynamically based on request data.

public function rules()
{
    $rules = [
        'name' => 'required|string|max:255',
    ];

    $this->when($this->input('is_admin'), function () use (&$rules) {
        $rules['admin_code'] = 'required|string|max:10';
    }, function () use (&$rules) {
        $rules['email'] = 'required|email|unique:users,email';
    });

    return $rules;
}

This approach dynamically adds validation rules for admin_code when is_admin is present, and for email otherwise.


The when() and unless() methods support chaining, enabling you to handle complex conditions elegantly.

public function store(Request $request)
{
    $request->when($request->filled('promo_code'), function ($request) {
        $request->merge(['discount' => 10]);
    })->when($request->boolean('is_vip'), function ($request) {
        $request->merge(['discount' => $request->input('discount') + 5]);
    });

    Order::create($request->all());

    return response()->json(['message' => 'Order placed successfully!']);
}

In this example, the discount is conditionally increased based on the presence of a promo code and the VIP status of the user.


Here are some of the benefits of using these methods:

  1. Readability: Simplify conditional logic into a more readable form.

  2. Inline Execution: Execute logic inline without relying on verbose if statements.

  3. Chaining: Handle multiple conditions seamlessly.

  4. Reusability: Easily extend or modify conditional logic.


The introduction of the Conditionable trait in Laravel’s Request class is a game-changer for developers looking to write clean, efficient, and maintainable code. The when() and unless() methods make it easy to conditionally execute logic and reduce the need for repetitive if-else blocks.

Start incorporating these methods into your Laravel applications to streamline your request handling today! If you have any questions or ideas, feel free to share them in the comments below.

Happy coding!