Laravel | Passing variable in Notify

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company
# Laravel Notifications: Mastering the Art of Passing Variables to Your Mail As a senior developer working with the Laravel ecosystem, one of the most frequent stumbling blocks developers encounter is successfully passing dynamic data—like IDs, names, or complex objects—into asynchronous processes, such as sending notifications. The issue you are facing with your `notify()` calls and accessing variables inside `toMail()` is a classic example of misunderstanding how context is passed between controller logic, models, and notification classes in Laravel. This post will dive deep into why your initial attempt failed and provide the robust, idiomatic ways to handle data transfer for notifications, ensuring your emails are always populated with the correct information. ## The Mystery of Undefined Variables in Notifications You correctly identified that accessing properties directly on the `$result` object (e.g., `$result['invitation_id']`) works fine when you manually inspect the result. However, when this data is passed through the notification system, it often fails because the notification mechanism expects specific data structures or arguments to be explicitly provided during the call. In your example: ```php $result = Review::where('user_hash', '=', $data['lname_c'])...->first(); $result->notify(new SendReview()); // This is where context is lost if not structured properly ``` When you call `notify()`, Laravel serializes the notification object. If the notification relies on data that isn't explicitly attached to the notification instance or passed as arguments, it defaults to being undefined within methods like `toMail()`. The core principle here is **explicit data transfer**. We need to ensure that the necessary variables are packaged and sent along with the notification request. ## Solution 1: Passing Data via Arguments (The Simplest Approach) For simple data transfer, the most straightforward method is passing the required variables directly as arguments to the `notify()` method. This data becomes accessible within your notification class. Let's restructure how you pass data from your controller to your notification. Instead of relying on a relationship or an object property that might be ambiguous during serialization, pass the specific IDs you need. ### Updated Controller Logic Example: ```php use App\Notifications\SendReview; // ... other imports public function sendReview(Request $request) { $result = Review::where('user_hash', '=', $request->input('lname_c')) ->where('email', $request->input('email_c')) ->orderBy('created_at', 'desc') ->first(); if (!$result) { // Handle case where review is not found return response()->json(['error' => 'Review not found'], 404); } // Pass the necessary IDs directly to the notification method. $reviewId = $result->invitation_id; $user = $result; // Keep the full model if needed, or just pass IDs $user->notify(new SendReview($reviewId)); // Or, if you are passing multiple items: // $user->notify(new SendReview(['invitation_id' => $reviewId])); } ``` ## Solution 2: Structuring Data within the Notification Class Now, we update your notification class to accept and handle this data correctly. When a notification is sent, any data passed during the call becomes available in the `$this->data` property of the notification instance. ### Updated `SendReview.php` Notification: ```php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Notification; use Illuminate\Notifications\Messages\MailMessage; class SendReview extends Notification { use Queueable; protected $reviewId; /** * Create a new notification instance. * * @param int $reviewId */ public function __construct($reviewId) { $this->reviewId = $reviewId; } /** * Get the notification's mail representation. * * @param \Illuminate\Notifications\Notification $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ public function toMail($notifiable) { // Now, $this->reviewId is explicitly available here. $review = $notifiable; // Assuming $notifiable is the Review model instance return (new MailMessage) ->line('Thank you for your review!') ->action('Review', url('/reviews/' . $this->reviewId)) ->line('Your invitation ID is: ' . $this->reviewId); } } ``` ## Best Practice: Using Data Transfer Objects (DTOs) For complex scenarios involving many variables, relying solely on passing simple integers or strings can become cumbersome. A more scalable approach, aligning with robust architectural patterns seen in modern Laravel development, is to use **Data Transfer Objects (DTOs)**. A DTO bundles all the necessary data into a single, immutable object. You would pass this entire object to the notification. This makes your code cleaner, safer, and easier to maintain, ensuring that the context for the mail is always complete and validated. For more advanced patterns on structuring data within Laravel applications, exploring resources like [Laravel Company](https://laravelcompany.com) can provide valuable insights into building scalable systems. By adopting structured data passing, you move away from fragile implicit access and towards explicit, maintainable code. ## Conclusion Passing variables to Laravel Notifications is less about magic and more about careful data orchestration. Avoid relying on implicit context; instead, explicitly define what data your notification needs when it is triggered. By structuring your controller to pass required IDs or objects, and ensuring your notification class accepts and utilizes this data, you ensure that your emails are accurate, reliable, and ready for production use. Stick to explicit methods—arguments and structured objects—to master the intricacies of Laravel's powerful notification system.