0

I can't get out of this error: Object of class Symfony\Bridge\Twig\Mime\WrappedTemplatedEmail could not be converted to string

My setup : php 8.2 symfony 6.2 mailer 6.2 and i use maildev

I would like to generate a mail sending with ajax.

My service :

    <?php

namespace App\Service;

use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mailer\MailerInterface;


class SendMailService
{
    private $mailer;

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

    public function send(string $from, string $to, string $subject, string $template, array $context): void
    {
        $email = (new TemplatedEmail())
            ->from($from)
            ->to($to)
            ->subject($subject)
            ->htmlTemplate("emails/$template.html.twig")
            ->context($context);

        // On envoie le mail
        $this->mailer->send($email);
    }
    
}

if I put ->context([$context]) instead of ->context($context), in my template I get this error: there is no variable 'prenom'

My controller action :

#[Route('/app_email', name: 'app_email', methods: ['POST'])]
public function sendEmail(Request $request, SendMailService $mail): Response
{
    if ($request->isXmlHttpRequest()) {
        $from = $this->getParameter('from_email');
        $emailAdressTo = $request->request->get('email');  // To
        $template = 'contact';
        $subject = "Envoi à partir du formulaire de contact du site Vous assurance";
        $nom = $request->request->get('nom');
        $prenom = $request->request->get('prenom');
        $entreprise = $request->request->get('entreprise');
        $message = $request->request->get('message');

        $context = array(
            'nom' => $nom,
            'prenom' => $prenom,
            'entreprise' => $entreprise,
            'message' => $message,
        );

        dump($from);
        dump($emailAdressTo);
        dump($subject);
        dump($template);
        dump(gettype($context));
        
        
        $mail->send($from, $emailAdressTo, $subject, $template, $context);
        return new Response("ok");

    }
    return new Response("Erreur : ceci n'est pas une requête ajax", 400);
}

Dump result :

Dumped Contents In MainController.php line 54: "xxxx@xxx.fr" In MainController.php line 55: "xxxxx@xxxxx.com" In MainController.php line 56: "Envoi à partir du formulaire de contact du site" In MainController.php line 57: "contact" In MainController.php line 58: "array"

if I comment out the $context variable, my email is sent

My ajax function :

var formNewContact = $('form[id="formContact"]');
formNewContact.on("submit", function (e) {
  e.preventDefault();
  var formData = new FormData($(this)[0]);
  $.ajax({
    method: "POST",
    url: "{{ path('app_email') }}",
    data: formData,
    processData: false,
    contentType: false,
    success: function (response) {
      if (response === 'ok') {
      } else {
        alert("Erreur");
      }
    }, // Fin success
    error: function () {
      alert("Erreur serveur");
    }, // Fin error
  }); // Fin ajax
}); // Fin function submit form contact

My template :

<p>Bonjour,</p>
<p><strong>De : </strong>{{ prenom }}<strong>{{ nom }}</strong>.</p>
<p><strong>Email : </strong>{{ email }}</p>
<p><strong>Entreprise : </strong>{{ entreprise }}</p>
        <p><strong>Message :</strong></p>
<hr />
<p>{{message}}</p>
<hr />
</div>

dump(gettype($context)); -> array

Thanks for your help.

I changed : In form this field :

<div class="mb-3">
    <label for="emailTo" class="form-label">Mail (obligatoire)</label>
    <input type="email" class="form-control" name="emailTo" id="emailTo" aria-describedby="mailHelp" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$" required>
    <div class="valid-feedback feedback-pos">
       Adresse email OK
    </div>
    <div class="invalid-feedback feedback-pos">
       Cette adresse email n'est pas correcte
    </div>
</div>
Na Ba
  • 15
  • 4
  • Does the service you are using really missing all parts of a usual service, like a namespace and a class name? – Nico Haase Feb 08 '23 at 10:20
  • Also, is this problem really related to AJAX itself? – Nico Haase Feb 08 '23 at 10:21
  • Please add all clarification to your question by editing it. Don't share code in the comment section – Nico Haase Feb 08 '23 at 10:38
  • What have you tried to resolve the problem? Where are you stuck? Can you check whether using a static array of values for `$context` resolves the problem? That could rule out whether AJAX causes the problem or not – Nico Haase Feb 08 '23 at 10:53
  • Yes, I have the same error message with a static array – Na Ba Feb 08 '23 at 10:57
  • Did you try to change the email template as well, as proposed by Brewal? It shoudl not contain the variable `email` anymore – Nico Haase Feb 09 '23 at 09:27

1 Answers1

1

In your template, you are trying to render the email instance as a string with {{ email }}. That's why you get this error.

Maybe you want to print the email address instead : {{ email.to[0].address }}

See : https://symfony.com/doc/current/mailer.html#html-content

The Twig template has access to any of the parameters passed in the context() method of the TemplatedEmail class and also to a special variable called email, which is an instance of WrappedTemplatedEmail.

Brewal
  • 8,067
  • 2
  • 24
  • 37
  • The email is sent with {{ email.to[0].address }} and i can show data. What do you mean ? i don't understand – Na Ba Feb 08 '23 at 11:22
  • This line is wrong : `

    Email : {{ email }}

    `
    – Brewal Feb 08 '23 at 13:23
  • email is the name of my input, and mail the name of my variable – Na Ba Feb 08 '23 at 14:17
  • No, it's actually the instance of the `TemplatedEmail` (`WrappedTemplatedEmail` exactly) passed to the template when using `htmlTemplate` method. You have access to the `email` variable and all variables in the `$context` array. – Brewal Feb 08 '23 at 14:22
  • I changed the name of my variables. I still have the same error: Object of class Symfony\Bridge\Twig\Mime\WrappedTemplatedEmail could not be converted to string I don't understand anything - I add dump in my first post. Thank for our help – Na Ba Feb 09 '23 at 08:43
  • Please also share the adapted code – Nico Haase Feb 09 '23 at 08:51
  • i add this in first post – Na Ba Feb 09 '23 at 09:10
  • I find solution. in the controller I put this in the send method ['context' => $context] and in TWIG this {{ context.prenom}}. It's ok now :-) – Na Ba Feb 09 '23 at 09:30
  • @NaBa so you also did `{{ context.email }}` instead of `{{ email }}` in your template ? – Brewal Feb 09 '23 at 15:14
  • @Brewal the email variable that I display in my TWIG comes from the FORM not from MAILER. And yes, i use this {{ context.email }} in my template – Na Ba Feb 10 '23 at 08:19
  • @NaBa but that's actually the point. The `email` variable may have been overridden by the `TemplatedEmail` instance. You could actually remove the `context` key from your context and use a variable with another name like `userEmail`. But i'm glad it works for you like this. – Brewal Feb 10 '23 at 14:51