I'm trying to use database driver for queuing emails. Using Mail::send emails are sent as expected. But when I use Mail::queue the user object passed to the view gets null "Trying to get property of non-object".
I have a mailer class and these are the methods responsible for sending the email:
public function sendAssignmentEmail(User $user)
{
$this->to=$user->email;
$this->view='emails.assigned';
$this->data=compact('user');
$this->subject='subject';
$this->deliver();
}
public function deliver()
{
$to=$this->to;
$subject=$this->subject;
$from=$this->from;
return $this->mailer->queue($this->view,$this->data, function($message)
use($to, $subject, $from)
{
$message->from($from, 'example.com');
$message->to($to);
$message->subject($subject);
});
}
What am I doing wrong?
I know that the problem is with the
$this->data
If I pass an array the queue will work, but if the data is in form of an object it won't.
Mail::queue is essentially exactly the same as Mail::send except your queuing them to be sent.
As a result it expects the same parameters as Mail::send in which the second argument needs to be an array, hence why it works when you supply an array and doesn't when you supply an object.
Simply change $this->data=compact('user'); to be in the form of an array and it'll work fine for you.
The docs are super useful when you get stuck on things like this :).
Related
EDIT:
I outputted the array and #apokryfos had mentioned something about resources not being able to be serialized.
Here is how some debug output looks: (Removed some information that is more sensitive)
Stream in Timestamp
It is my timestamp causing the issue. If I do
unset($user["timestamp"]);
Then almost everyone's solution works. So, the real reason was the resources was in there for my timestamp. How do I stop or fix that? I tried to do
public $timestamps = false;
This did not have any changes.
I have read through the documentation and a few tutorials. Sadly, I can't seem to find any documentation on what is returned and what functions are available for use when using Eloquent. Maybe I am just missing it.
However, I am using this code in my controller.
public function find($userName){
$user = UserSecurity::where('userName', $userName)->get();
//dd($user);
return Response()->json(['data' => $user], 200);
}
This is my router code.
$router->get('/UserSecurity/find/{userName}', ['uses'=>'UserSecurityController#find']);
I know that it is pulling the correct data from the database as if I uncomment the dd($user) I can see it on screen. However, if I try to send a response through Response()->json(..) it fails with this screen.
Image of Exception
I know I am probably using Response() incorrectly, but I have actually tried a number of different ways. Some just show empty responses and some crash similarly.
I have tried removing get() which from what I have found just returns nothing as there are no results. I have tried Response($user) and it was empty. I have tried return Response()->json($user); with the same type unsupported error.
Thanks for any help.
EDIT:
Changing a few code for testing. I changed to this
public function find($userName){
$user = UserSecurity::where('userName', $userName)->get()->toJson();
$user = json_encode($user);
return Response($user);
}
This returns false . I am not sure where the boolean is coming from. The original dd($user) actually has the correct information from the DB, so I know it is doing the query correct.
I think you must add the following in the top of your controller
then this code will help you.
use Illuminate\Support\Facades\Response;
The error message Type is not supported is actually coming from PHP's JSON serializer. There are only a very few types that PHP cannot serialise and the one that seems to be causing the issue in your particular case is a stream resource.
In order to check what is actually serialized in your model you will need to call:
$user = UserSecurity::where('userName', $userName)->get();
$user->map->jsonSerialize()->dd();
jsonSerialize exists because all Laravel models implement the JsonSerializable interface.
This will dump a collection of arrays of what PHP will attempt to serialise as JSON. The contents of this array are recursively serialised.
The default implementation of JsonSerializable in Model will attempt to serialize all model attributes but first will attempt to cast and call all accessors on attributes. This may or may not cause issues. At any rate the solution here is to figure out why there's a resource being returned in the jsonSerialize method and figure out the best way to hide it. Normally you can hide attributes by using
protected $hidden = [ 'timestamp' ];
however from your question it seems that the answer may not be so straight forward so may need to dig deeper.
I think you must add the following in the top of your controller:
use Illuminate\Support\Facades\Response;
and the controller must be like:
public function find($userName){
$user = UserSecurity::where('userName', $userName)->get();
return Response::json($user, 200);
}
PLease try like this
return response()->json(['status' => true, 'data' => $user],200);
I am already using this in my code
Using where('...')->get() returns a collection which cannot be used in response()->json().
Try using:
public function find($userName){
$user = UserSecurity::where('userName', $userName)->first();
return response()->json(['data' => $user->toArray()], 200);
}
here is just a typo error, you must write response() in lowercase instead or Response() because Response is a class, while response() is a magic Laravel function which already instantiates the class Response, and that you can use to return a Response instance.
I need to get laravel mail as variable and to pass in it model object
$markdown = new Markdown(view(), config('mail.markdown'));
$html = $markdown->render($template, $user->toArray());
Here is the problem I am not getting relations within array and I know that I can use with to pass relations, but I am wondering is there a better way of getting laravel mail as HTML variable?
Is there maybe I way to create new mail like PHP artisan make:mail Test and then to call that test mail class and get full filled mail as HTML?
Seems like doing this helps:
return (new Welcome(User::find(1)))->build();
This is returning mail html
I've been having this issue where I want to send a plaintext email to a user (me in this case) but the email adress is inside of an object I retrieved from the database. All examples using Mail::raw use a string but not a passed variable. Is there a way to do that?
Code:
Mail::raw($messageContent, function($message)
{
$message->to($foo->email);
});
This is what I want, in essence. $foo is a variable declared in the function that this is in. I don't want to make $foo a class variable because I am only using it here.
Thanks for helping!
Mail::raw($suggestionString, function($message) use ($follower)
{
$message->to('support#company.com')->subject('Suggestion')->replyTo($follower->email);
});
When you reply to this message it's automatically sent to the email specified in ->replyTo()
Is there a way to get the message-id of the to be send email within Laravel Mailables?
I currently get the id like this which just works fine, but since this doesn't support markdowns and stuff, I would prefer to get around this:
Mail::send('mail.contact.confirmation', $contactData, function (Message $message) use ($mailTo, $subject, &$headers)
{
$headers['message-id'] = $message->getSwiftMessage()->getId();
$message->to($mailTo)->subject($subject);
});
Thanks for any advice.
I just had to figure this out on my own, so take my answer with a grain of salt (although it works for me).
Within the "build()" function of a Laravel Mailable, you can do:
$this->withSwiftMessage(function ($swiftmessage) {
echo $swiftmessage->getId();
});
Hopefully that gets you started. My use-case was editting the ID, so I used:
$this->withSwiftMessage(function ($swiftmessage) use ($newId) {
$swiftmessage->setId($newId);
return $swiftmessage;
});
I had the same challenge where I had to run a Laravel Queue where message ID should be displayed after sending an email. I solved this issue like this.
namespace App\Jobs
inside handle()
$message_Id="";
Mail::send('emails.thanks',array(),function($message) use(&$message_Id){
$message_Id=$message->getId();
$message->to('enter email id','any name')->subject('Please check the message ID');
});
echo $message_id;
I am new to Laravel and am building a small project as my schooling. I have struck the above error and I cannot seem to fix it. Any help is appreciated.
In my controller I make the following call when first loading the page. The getDetails method works perfectly on page load, but fails with above error when I call it with Ajax as the user interacts with the page after load.
On page load the method is called and passed to it resulting values from earlier other method calls ($CSpec[0]->id and $CSize[0]->size_mm, which I can see as values 1 and 0.5) as follows:
$CD = CS::getDetails($CSpec[0]->id, $CSize[0]->size_mm);
Also in the controller I have the following function which triggered via a route used in an Ajax call:
public function itemDetails($ct, $cs)
{
return CS::getDetails($ct, $s);
}
The getDetails method looks like this:
public static function getDetails($ct, $cs)
{
return DB::table('recommend_view')
->where('recommend_view.id', '=', $ct)
->where('recommend_view.size_mm', '=', $cs)
->first();
}
I have this route:
Route::get('vd/cd/{cd}/{cs}',
['uses' => 'Application\VDController#itemDetails', 'as' => 'application.vdcdetails']);
When I use Ajax to call the same method it fails with the above error. The Ajax code produces the following url in the $.getJSON call:
http://my.app/vd/cd/1/0.5
If I dd() inside getDetails for each variable I can see the correct values passed to the method from the url / controller.
If I execute the query in MySQL Workbench, it works as expected:
select *
from `recommender_view`
where `recommender_view`.`ct_id` = 1
and `recommender_view`.`cs_size_mm` = 0.50
limit 1;
So the method works perfectly when called on initial page load with variables fed to it directly from other method calls, but when the variables are passed via the URL / Ajax it fails and I cannot seem to understand what the difference is.
UnexpectedValueException in Response.php line 403:
The Response content must be a string or object implementing __toString(), "object" given.
I believe I know what your issue is, however, please feel free to correct me.
What you're using is the Laravel query builder, which returns a stdClass object type in PHP, assuming it finds a result set for your query. This is effectively a "dumb" object that has no methods to "echo" or return. You can't cast to array, nor json etc.
So when the Laravel response object is trying to handle it, it can't use the __toString() method to deconstruct an appropriate response.
What you'd be better off doing is calling the query against a Model that extends the Illuminate Eloquent Model class.
In this instance, it COULD be something like this
CableRecommenderView::where('recommend_view.id', $ct)
->where('recommend_view.size_mm', $cs)
->first();
Eloquent is able to respond accordingly when being passed to the response object.
As an FYI, when using equals ('=') as the comparison operator in queries Eloquent (and possibly the query builder, although you'd have to check on that), you can forego explicitly defining it in the ->where() clause and simply pass the comparison variable as the second argument.
Hope that helps!
The ajax call expects a response to be passed back to it. It is unable to recognize the object you are trying to pass to it.
Look into creating responses http://laravel.com/docs/5.1/responses.
If you return a json response e.g
public function itemDetails($ct, $cs)
{
$item = CS::getDetails($ct, $s);
return response()->json(['data' => $item]);
}
The ajax call should work. Then you can retrieve from the data variable from your ajax.