Reputation: 1868
I'm trying to send the collected variables of this ticket to my markdown email in Laravel.
I'm getting this error
"Trying to get property of non-object" and cannot figure out how to pass all the variables into my markdown email.
Here are the steps I'm taking:
Route:
Route::post('/admin', 'AdminController@emailOpenStoreTicket')->name('email-open-store');
Form to gather ticket data:
<form action="{{route('email-open-store')}}" method="POST" enctype="multipart/form-data">
@csrf
{{method_field('post')}}
<input type="email" name="staff_email" required>
<textarea name="rec_message" required></textarea>
<input type="hidden" name="subject" value="{{ $ot->subject}}">
...etc
<input type="hidden" name="street" value="{{ $ot->street }}">
<button type="submit">Send</button>
</form>
Admin Controller:
public function emailOpenStoreTicket(Request $request)
{
$validatedData = $request->validate([
'staff_email' => 'required|email',
'rec_message' => 'required|min:2'
]);
$ticket = new EmailOpenTicket;
$ticket->staff_email=$request->staff_email;
$ticket->rec_message=$request->rec_message;
$ticket->subject=Purifier::clean($request->subject);
$ticket->content=Purifier::clean($request->content);
$ticket->username=$request->username;
$ticket->user_id=$request->user_id;
$ticket->street=$request->street;
$ticket->first_name=$request->first_name;
$ticket->last_name=$request->last_name;
$ticket->email=$request->email;
$ticket->file_name=$request->file_name;
Mail::to($ticket->staff_email)->send(new EmailOpenTicket);
return back()->with('success','Your email message has been sent.');
}
Mail Class If I use:
public function __construct(Ticket $ticket)
{
$this->ticket = $ticket;
}
It errors the following:
Type error: Too few arguments to function App\Mail\EmailOpenTicket::__construct(), 0 passed in app\Http\Controllers\AdminController.php on line 71 and exactly 1 expected
Which is this line in the above Admin Controller: $ticket = new EmailOpenTicket;
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Ticket;
use App\Admin;
class EmailOpenTicket extends Mailable
{
use Queueable, SerializesModels;
public $ticket;
/**
* Create a new message instance.
*
* @return void
*/
// public function __construct(Ticket $ticket)
// {
// $this->ticket = $ticket;
// }
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->subject('New Open Maintenance Ticket')->markdown('admin.tickets.emailopenticket');
}
}
Then my email view:
I read that if I add the ['ticket' => $ticket]
it will help pull in the variables... In this case it skips ['ticket' => $ticket]
and error on the next line:
Trying to get property of non-object
@component('mail::message', ['ticket' => $ticket])
#{{$ticket->rec_message}}
{{$ticket->first_name}} {{$ticket->last_name}} has submitted a new maintenance ticket.
Please review and complete as soon as possible
@component('mail::panel')
**Details:**
- **Ticket Type:** Maintenance Request
- **Ticket Number:** {{$ticket->st_id}}
- **Subject:** {{$ticket->subject}}
..etc
I've been at this for 2 days. Would be grateful if someone could lend a hand
Upvotes: 2
Views: 8001
Reputation: 13467
If your EmailOpenTicket
class' constructor defines a required parameter, you need to pass it in when instantiating the class.
// Assuming $ticket is already defined as a Ticket object:
$email = new EmailOpenTicket($ticket);
Also, when you send the Mailable, make sure to pass in the instance you already created and assigned data to. In your code example, you're instantiating a second EmailOpenTicket
class.
Mail::to($ticket->staff_email)->send($ticket);
To provide some additional advice: it seems like Ticket
is already a model with data in the database. If that is the case, you don't really need to send all of its data through the form. All you need is the ID of the Ticket you want to send. Then, your controller can find that Ticket, attach it to the Mailable, and be on your way.
Form:
<form action="{{route('email-open-store')}}" method="POST" enctype="multipart/form-data">
@csrf
{{method_field('post')}}
<input type="email" name="staff_email" required>
<textarea name="rec_message" required></textarea>
<input type="hidden" name="ticket_id" value="{{ $ot->id }}">
<button type="submit">Send</button>
</form>
Controller:
public function emailOpenStoreTicket(Request $request)
{
$validatedData = $request->validate([
'staff_email' => 'required|email',
'rec_message' => 'required|min:2',
// Validate the ticket ID exists in the DB
'ticket_id' => 'required|exists:tickets,id'
]);
// Grab the Ticket via Eloquent
$ticket = Ticket::findOrFail($request->ticket_id);
// Create the Mailable, passing in the Ticket
$email = new EmailOpenTicket($ticket);
$email->staff_email = $request->staff_email;
$email->rec_message = $request->rec_message;
Mail::to($email->staff_email)->send($email);
return back()->with('success','Your email message has been sent.');
}
Mailable:
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Ticket;
use App\Admin;
class EmailOpenTicket extends Mailable
{
use Queueable, SerializesModels;
public $ticket;
public $staff_email;
public $rec_message;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(Ticket $ticket)
{
$this->ticket = $ticket;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->subject('New Open Maintenance Ticket')->markdown('admin.tickets.emailopenticket');
}
}
Upvotes: 3