Simon Cooper
Simon Cooper

Reputation: 1594

sending email from form - protocol String.Chars not implemented

I have a simple contact form sending email and message fields. I'm using Mailgun.

I can send an email perfectly from the console, but when I try and send from the form in the UI, I receive the following error:

protocol String.Chars not implemented for %Iotc.Contact.Email{__meta__: 
#Ecto.Schema.Metadata<:loaded, "contact_emails">, email: 
"[email protected]", id: 25, inserted_at: ~N[2017-06-15 10:34:26.229957], 
message: "I'd like a cake please.", updated_at: ~N[2017-06-15 10:34:26.229977]}

email_controller.ex

  def create(conn, %{"email" => email_params,
                   "email" => %{"email" => email,
                   "message" => message}}) do

    changeset = Contact.Email.changeset(%Iotc.Contact.Email{}, email_params)
    case Contact.create_email(email_params) do
      {:ok, email} ->
        Iotc.Mailer.send_email(email, message) #<this is the issue.
        conn
        |> put_flash(:info, "Email sent")
        |> redirect(to: email_path(conn, :index))
      {:error, changeset} ->
        conn
        |> put_flash(:error, "Something went wrong")
        |> render("index.html", changeset: changeset)
    end

I've tried changing

Iotc.Mailer.send_email(email, message)

to

Iotc.Mailer.send_email(email_params)

But I then get

key :to not found in: %{"email" => "[email protected]", "message" => "I'd like a cake please.", "name" => "Simon"}

Upvotes: 0

Views: 271

Answers (1)

Dogbert
Dogbert

Reputation: 222198

The pattern {:ok, email} shadows the outer email string value with a %Iotc.Contact.Email{} struct while send_email expects the first argument to be just the email address string value. You can get the address value by doing email.email:

case Contact.create_email(email_params) do
  {:ok, email} ->
    Iotc.Mailer.send_email(email.email, message)
    ...
  ...
end

or you can change the pattern to ignore the returned struct since you're not using it anyways:

case Contact.create_email(email_params) do
  {:ok, _} ->
    Iotc.Mailer.send_email(email, message)
    ...
  ...
end

Upvotes: 1

Related Questions