2

In my UserController I have a function

public function userFollow($id)
    {
        $authuser = Auth::user();
        $authuser->follow($id);
        //mail goes to the followiee ($id)
        $followiee = User::where('id', $id)->first();
        $to = $followiee->email;
        Mail::to($to)->send(new MyMail);
        return redirect()->back()->with('message', 'Following User');
    }

I have also created a Mailable MyMail

class MyMail extends Mailable
{
    use Queueable, SerializesModels;


    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.welcome');
    }
}

Inside my welcome email I need to access some variables like $to which is defined in the UserController

I tried the following in MyMail Mailable:

 public function build()
    {
        return $this->view('emails.welcome',['to' => $to]);
    }

But I am getting Undefined variable: to

How to pass variables from Controller to Mailables?

Update:

What I have tried so far:

UserController

Mail::to($to)->send(new MyMail($to));

MyMail

    public $to;
    public function __construct($to)
    {
        $this->to = $to;
    }

    public function build()
    {
        return $this->view('emails.welcome');
    }

Welcome.blade.php

 {{ $to }}

Error:

FatalErrorException in Mailable.php line 442:
[] operator not supported for strings

2 Answers 2

8

One solution is to pass variables to the MyMail constructor, like this:

UserController

Mail::to($to)->send(new MyMail($to));

MyMail

public $myTo;

public function __construct($to)
{
    $this->myTo = $to;
}

public function build()
{
    return $this->view('emails.welcome');
}

Welcome.blade.php

{{ $myTo }}

Update: As @Rahul noted in his answer, the $to property can be defined as public. And in this case the view will be populated with it automatically.

Update 2: You just need to give a different name to your $to variable (e.g. $myTo) to distinguish it from the $to in the Mailable.php which is defined as public $to = [];.

Sign up to request clarification or add additional context in comments.

5 Comments

I tried this, but I am getting an error Access level to App\Mail\MyMail::$to must be public (as in class Illuminate\Mail\Mailable)
In order to make public you dont need to pass it as parameter, see the method 1 of below solution
I tried @Rahul method too, but I got another error FatalErrorException in Mailable.php line 442: [] operator not supported for strings
Awesome, changing it to a different variable worked!
So trying to pass a custom string variable in the constructor of a mailable in Laravel 5.5 gives me a BindingResolutionException, saying "Unresolvable dependency resolving" as if it thinks the string is a dependency... Is it required to pass only dependency objects in 5.5 or am I doing something wrong?
2

There are two ways you may make data available to your view.

  1. First, any public property defined on your mailable class will automatically be made available to the view
class MyMail extends Mailable
{
    use Queueable, SerializesModels;

    public $to;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($to)
    {
        $this->to = $to;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.welcome'); // $to will be automatically passed to your view
    }
}
  1. Second you may manually pass your data to the view via the with method however you will still pass data via the mailable class' constructor; however, you should set this data to protected or private properties so the data is not automatically made available to the template.
class MyMail extends Mailable
{
    use Queueable, SerializesModels;

      protected $to;
    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($to)
    {
        $this->to = $to;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.welcome',['to'=>$to]);


     }
    }

4 Comments

in the 1st method, you have not passed $to in the constructor. Although I tried your 1st method by passing the variable to the constructor, it didnt work for me.
@thehackwall I have written $this->to = $to; in 1st method
But you need to pass the argument like this also right? public function __construct($to)
ohhh yes my mistake

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.