1

I am trying to pass non-model data to my email blade. I however keep getting this error.

Cannot unpack array with string keys

I have tried using the following post but didn't get to resolve the issue I am having.

Here is my controller:

$data = ['email'=> $email, 'token'=> $token, 'name'=> $name];
        sendMailWithMailerClass($email, '\App\Mail\ApplicantSetPasswordMail', $data);
        
...



function sendMailWithMailerClass($mailTo, $mailerClass, $mailerClassParams)
{
  
    try{
        Mail::to($mailTo)->send(new $mailerClass(...$mailerClassParams));
    } catch (Exception $e) {
       
    }
}
The email class is here below

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class ApplicantSetPasswordMail extends Mailable
{
    use Queueable, SerializesModels;
    public $data;

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

    
    public function build()
    {
        return $this->markdown('emails.applicant_set_password', compact('data'));
    }
}

Here is my email view:

<!DOCTYPE html>
<html lang="en" >
<head>
</head>

<body >
<center>
    
    <p>Dear {{ $data['name'] }},</p>
    <p style="margin-bottom: 25px;">Text</p>
    <a href="{{ URL::to('/').'/url/?email='.$data['email'].'&token='.$data['token'] }}" >Set Password</a>
                     
</center>
</body>
</html>

3
  • you mean you need to pass data to view of email right? return $this->markdown('emails.applicant_set_password'); on you didnt give any parameter to your view, use with() to pass your parameter data Commented Jun 23, 2020 at 4:54
  • I have done that, still the same error Commented Jun 23, 2020 at 5:04
  • show your code how you call the mail class Commented Jun 23, 2020 at 5:21

2 Answers 2

2

The splat operator ... that you try to use on the line new $mailerClass(...$mailerClassParams) cannot work with an associative array like your $data

I can see that the constructor you use for your mailable class is public function __construct($data) so you should be able to just use new $mailerClass($mailerClassParams)

If you do have a mailable class with multiple parameters in the constructor such as public function __construct($email, $token, $name) then you can either still pass it as 1 array parameter and check the content of the array passed. or use new $mailerClass(...array_values($mailerClassParams)). However, take note that if you use end up using array_values() then the order of the array actually matters as that is how it will map the parameters so that first entry of $mailerClassParams array will always be the first parameter, as such this is not the recommended way.

function sendMailWithMailerClass($mailTo, $mailerClass, $mailerClassParams)
{
    try{
        // Remove ... splat operator here
        Mail::to($mailTo)->send(new $mailerClass($mailerClassParams));
    } catch (Exception $e) {
       
    }
}

// make sure all your $mailClass constructors take 1 parameter
public function __construct($data)
{
    $this->data = $data;
}

OR

function sendMailWithMailerClass($mailTo, $mailerClass, $mailerClassParams)
{
    try{
        // Remove keys of the associative array with array_values
        Mail::to($mailTo)->send(new $mailerClass(...array_values($mailerClassParams)));
    } catch (Exception $e) {
       
    }
}

// make sure all constructor takes correct parameters in the correct order
public function __construct($email, $token, $name)
{
    $this->data = [
        'email' => $email,
        'token' => $token,
        'name' => $name,
    ];
}
Sign up to request clarification or add additional context in comments.

2 Comments

The first error has been resolved. How am I supposed to access the variables in my blade please. I used {{ $name }} and {{ $data['name'] }} both threw errors. I used the first approach
@mykoman instead of compact($data) pass $this->data as the data property is already an array, then you should be able to use it in your view with {{ $name }}
2

It is implemented since PHP 8.1.

$args = [
    ...['z' => 2, 'x' => 3],
    ...['y' => 1, 'x' => 4],
];

class Foo
{
    public function __construct(int $x, int $y, int $z)
    {
        echo <<<OUTPUT
            x = $x
            y = $y
            z = $z
        OUTPUT;
    }
}

new Foo(...$args);
/* Output:
 * x = 4
 * y = 1
 * z = 2
 */

Test it online!

Comments

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.