arcanemachine

arcanemachine

Programming Phoenix LiveView B9.0: "The Promo Live View" section does not work without modification when using Phoenix ~> 1.7.3 and LiveView ~> 0.19.0 (p. 130)

Disclaimer: I hope all of this is accurate, and not the result of some stupid typo I failed to notice. Anyways…

This post comprises 2 issues in the same section “The Promo Live View”. The first issue is relatively minor, but the second issue required some digging to fix:

  1. The PDF e-book contains an image on page 132 that shows a basic promo page in the browser (ie. no form is visible). However, the code sample on the previous page contains a <.simple_form> Live Component which will not properly render until after the code below the aforementioned image has been added. I am guessing the intention was to show the basic rendered page before adding the form component. By adding the code snippet on page 132, the issue is resolved. No big deal. However, another issue arose as I continued…

  2. On page 133, the code snippet presents <.simple_form> component contains an <.input> component that binds the field attribute as follows:

<.input field={{f, :first_name}} type="text" label="First name" />
<.input field={{f, :email}} type="email" label="Email address" phx-debounce="blur" />

However, when using Phoenix ~> 1.7.3 and LiveView ~> 0.19.0, this results in the following error:

key :name not found in: %{
  id: nil,
  label: "First name",
  type: "text",
  prompt: nil,
  field: {%Phoenix.HTML.Form{
     source: #Ecto.Changeset<
       action: nil,
       changes: %{},
       errors: [
         first_name: {"can't be blank", [validation: :required]},
         email: {"can't be blank", [validation: :required]}
       ],
       data: #Pento.Promo.Recipient<>,
       valid?: false
     >,
     impl: Phoenix.HTML.FormData.Ecto.Changeset,
     id: "promo-form",
     name: "recipient",
     data: %Pento.Promo.Recipient{first_name: nil, email: nil},
     hidden: [],
     params: %{},
     errors: [],
     options: [
       method: "post",
       id: "promo-form",
       multipart: false,
       "phx-change": "validate",
       "phx-submit": "save"
     ],
     index: nil,
     action: nil
   }, :first_name},
  errors: [],
  rest: %{},
  multiple: false,
  __changed__: nil,
  __given__: %{
    label: "First name",
    type: "text",
    field: {%Phoenix.HTML.Form{
       source: #Ecto.Changeset<
         action: nil,
         changes: %{},
         errors: [
           first_name: {"can't be blank", [validation: :required]},
           email: {"can't be blank", [validation: :required]}
         ],
         data: #Pento.Promo.Recipient<>,
         valid?: false
       >,
       impl: Phoenix.HTML.FormData.Ecto.Changeset,
       id: "promo-form",
       name: "recipient",
       data: %Pento.Promo.Recipient{first_name: nil, email: nil},
       hidden: [],
       params: %{},
       errors: [],
       options: [
         method: "post",
         id: "promo-form",
         multipart: false,
         "phx-change": "validate",
         "phx-submit": "save"
       ],
       index: nil,
       action: nil
     }, :first_name},
    __changed__: nil
  },
  inner_block: []
}

I made a couple small changes to get things working:

lib/pento_web/live/promo_live.html.heex (Modify the <.input> components)
  <.input field={f[:first_name]} type="text" label="First name" phx-debounce="500" />
  <.input field={f[:email]} type="email" label="Email address" phx-debounce="blur" />

I took inspiration for these changes by copying from the LiveView docs.

However, a different section of the same docs page suggests that the current approach taken by the book is discouraged and that a different approach should be used. I’m looking into this now (and I’m way out of my league… I am not up to snuff on using forms in Phoenix/LV) and will suggest a revised approach if I can 1) figure it out, and 2) get it working with the process described in the book.

Marked As Solved

SophieDeBenedetto

SophieDeBenedetto

Author of Programming Phoenix LiveView

Thanks for your submission! We’re hard at work updating all of the code in the book for the latest release, and the issues you point out here should be addressed by that.

Also Liked

arcanemachine

arcanemachine

OK, I whipped up an implementation based on some of the examples found in the generated code created while I was working on the project. I don’t know if it’s better. All I know is that it works, it matches the style of the generated code (which I assume is reasonably relevant), and it matches the info I found on this LiveView docs page that I referenced in my original post.

lib/pento_web/live/promo_live.ex
defmodule PentoWeb.PromoLive do
  use PentoWeb, :live_view
  alias Pento.Promo
  alias Pento.Promo.Recipient

  @impl true
  def mount(_params, _session, socket) do
    changeset = Promo.change_recipient(%Recipient{})

    {:ok, socket |> assign_form(changeset)}
  end

  defp assign_form(socket, %Ecto.Changeset{} = changeset) do
    assign(socket, :form, to_form(changeset))
  end

  @impl true
  def handle_event("validate", %{"recipient" => recipient_params}, socket) do
    changeset = %Recipient{}
      |> Promo.change_recipient(recipient_params)
      |> Map.put(:action, :validate)

    {:noreply, assign_form(socket, changeset)}
  end

  def handle_event("save", %{"recipient" => recipient_params}, socket) do
    changeset = %Recipient{}
      |> Promo.change_recipient(recipient_params)

    if changeset.valid? do
      {:noreply, socket |> put_flash(:info, "Form submitted successfully.")}
    else
      {:noreply,
       socket
       |> put_flash(:error, "Please fill out the form correctly before continuing.")}
    end
  end
end
lib/pento_web/live/promo_live.html.heex
<.header>
  Send Your Promo Code to a Friend
  <:subtitle>promo code for 10% off their first game purchase!</:subtitle>
</.header>

<.simple_form
  for={@form}
  id="promo-form"
  phx-change="validate"
  phx-submit="save"
>
  <.input field={@form[:first_name]} type="text" label="First name" />
  <.input field={@form[:email]} type="email" label="Email address" phx-debounce="blur" />

  <:actions>
    <.button phx-disable-with="Sending...">Send Promo</.button>
  </:actions>
</.simple_form>
lurnid

lurnid

I’m going through B10.0 and agree with point 1 of the OP. The B10.0 book, at the end of p 137 says:

Start up the server, log in, and point your browser at /promo. You should see the following:

But trying to view the /promo path at this point will throw an error because the code that follows on pp 138 is needed for the page to load successfully.

It would be better to not ask the reader to load the /promo path until after the code on pp 138 otherwise (as I did) the will end up thinking that the error was due to a mistake in the code they wrote rather than the fact that the code isn’t complete for rendering the view.

mostalive

mostalive

For me the problem here was that the code for the <.simple_form appeared too early (page 136 and 137 in PDF B10.0 ). It is explained, and re-appears later on page 139.
Without <simple_form the live view worked, and seeing the page gave me a sense of progress. Adding the form on page 139, once the wiring was there, was smooth.

Where Next?

Popular Pragmatic Bookshelf topics Top

GilWright
Working through the steps (checking that the Info,plist matches exactly), run the demo game and what appears is grey but does not fill th...
New
jesse050717
Title: Web Development with Clojure, Third Edition, pg 116 Hi - I just started chapter 5 and I am stuck on page 116 while trying to star...
New
alanq
This isn’t directly about the book contents so maybe not the right forum…but in some of the code apps (e.g. turbo/06) it sends a TURBO_ST...
New
swlaschin
The book has the same “Problem space/Solution space” diagram on page 18 as is on page 17. The correct Problem/Solution space diagrams ar...
New
curtosis
Running mix deps.get in the sensor_hub directory fails with the following error: ** (Mix) No SSH public keys found in ~/.ssh. An ssh aut...
New
jskubick
I’m running Android Studio “Arctic Fox” 2020.3.1 Patch 2, and I’m embarrassed to admit that I only made it to page 8 before running into ...
New
oaklandgit
Hi, I completed chapter 6 but am getting the following error when running: thread 'main' panicked at 'Failed to load texture: IoError(O...
New
s2k
Hi all, currently I wonder how the Tailwind colours work (or don’t work). For example, in app/views/layouts/application.html.erb I have...
New
kolossal
Hi, I need some help, I’m new to rust and was learning through your book. but I got stuck at the last stage of distribution. Whenever I t...
New
mert
AWDWR 7, page 152, page 153: Hello everyone, I’m a little bit lost on the hotwire part. I didn’t fully understand it. On page 152 @rub...
New

Other popular topics Top

siddhant3030
I’m thinking of buying a monitor that I can rotate to use as a vertical monitor? Also, I want to know if someone is using it for program...
New
brentjanderson
Bought the Moonlander mechanical keyboard. Cherry Brown MX switches. Arms and wrists have been hurting enough that it’s time I did someth...
New
AstonJ
There’s a whole world of custom keycaps out there that I didn’t know existed! Check out all of our Keycaps threads here: https://forum....
New
Exadra37
Oh just spent so much time on this to discover now that RancherOS is in end of life but Rancher is refusing to mark the Github repo as su...
New
PragmaticBookshelf
Build efficient applications that exploit the unique benefits of a pure functional language, learning from an engineer who uses Haskell t...
New
PragmaticBookshelf
Author Spotlight: VM Brasseur @vmbrasseur We have a treat for you today! We turn the spotlight onto Open Source as we sit down with V...
New
hilfordjames
There appears to have been an update that has changed the terminology for what has previously been known as the Taskbar Overflow - this h...
New
First poster: bot
zig/http.zig at 7cf2cbb33ef34c1d211135f56d30fe23b6cacd42 · ziglang/zig. General-purpose programming language and toolchain for maintaini...
New
AstonJ
If you’re getting errors like this: psql: error: connection to server on socket “/tmp/.s.PGSQL.5432” failed: No such file or directory ...
New
NewsBot
Node.js v22.14.0 has been released. Link: Release 2025-02-11, Version 22.14.0 'Jod' (LTS), @aduh95 · nodejs/node · GitHub
New

Sub Categories: