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.

What is the when() Method?

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.

Method Signature:

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.


Using the when() Method

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

Example: Conditional Merging of Request Data

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.


Using the unless() Method

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

Example: Defaulting Missing Fields

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.


Dynamic Validation Rules

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

Example: Conditional Validation in a Custom Request Class

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.


Chaining Multiple Conditions

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

Example: Applying Multiple Conditions

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.


Why Use when() and unless()?

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.


Conclusion

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!