Title: Programming Phoenix LiveView
I am not sure if this an appropriate way to send feedback for this book. It seems like the defacto is to send a new thread for each error, but honestly I dont have the patience for that.
Its easier for me to just quickly note something down and send it out at bulk as I go - this way I dont break up my study flow.
This is the errors/inconsistencies I found from page 100 - 194. I plan on continuing to do this for the rest of the book, however if I am breaking conventions, I’ll avoid posting the next round here.
Book version: P1.1—May, 2026
p115: The explanation of the code snippet is incorrect.
p119: Snippet shows live_patch, but it's actually live_navigate.
p121: There is no handle_params here.
p131: "Live component" is used with no prior introduction — it isn't mentioned anywhere before this, including in the generated code.
p132: "The generators built two different components: a function component to handle a modal window and a live component to process a form." — not accurate for the latest generator.
p133: "How does the ProductLive.Show live view use the handle_params/3 callback?" — there is no handle_params here.
p159: The last paragraph feels out of place — unclear why it's included at this point.
p163: References closing `</.form>`, but the snippet uses `</.simple_form>`.
p163: `<.live_img_preview>` doesn't appear in the code snippet above it — unclear how it fits with the rest of the code.
p164: `upload_error_to_string` and `upload_image_error` don't exist.
p167: "We can modify the function for the :new action in the same way." — this feels out of place and repetitive. The preceding section already covered a shared implementation for both edit and new (updating product params before save_product is called), so this line contradicts how that was set up.
p178: "The references(:users, on_delete: :nothing) field builds a referential constraint" — should be `on_delete: :delete_all`.
p182: `product_fixture()` needs the scope passed in — it's `product_fixture/1`.
p182: There is no `user_fixture`, only `user_scope_fixture`, and the text doesn't make use of it. It's left to the caller to indirectly use it when provisioning the scope.
p182: The code snippet doesn't match the changes being described — it's identical to the generated code.
p183: `mix ecto.reset` fails with a "product_id column could not be found" error, because the product_id column isn't added in the ratings table migration. Resolved by adding:
`add :product_id, references(:products, on_delete: :delete_all), null: false`
This isn't mentioned in the text — it seems to assume the column was already in the generated migration.
p183: You can't register a user with a password — `email_changeset` only supports email.
p184: `create_demographic` also takes in scope.
p184: `list_products` needs the scope.
p184: The product is associated with user 1, so a rating can't be created for that user. It'd be better to either create a new product for that user, or just use user1 (which is what I ended up doing).
p184: The rating creation function takes in scope, which means attrs doesn't need user_id.
p187: Duplicate `i` call in the iex example — also the output of the first call looks incorrect.
p191: The app layout isn't specified in the `live_view` function in the generated code.
p194: "add it to the socket.assigns.user" — should be `socket.assigns.current_scope.user`.
p194: "assigns already contains the :current_user key" — should be `:current_scope`. Maybe clearer as "assigns' current scope already contains a :user key".