Programming Phoenix LiveView: Typo

Hi! I know not the intentions behind this narrative when called, on page XI:

mount() |> handle_event() |> render()

but the correct flow, it’s:

mount() |> render()  |> handle_event() |> render()

On page XII, it’s missing the content about chapter 1.

On page 12, when show the dependencies and theirs versions of… its a little bit different then a clean install, look up:

the boot dependencies:

{:bcrypt_elixir, "~> 2.0"}, # this dependency was depends on the clean install
{:phoenix, "~> 1.5.3"},
{:phoenix_ecto, "~> 4.1"},
{:ecto_sql, "~> 3.4"},
{:postgrex, ">= 0.0.0"},
{:phoenix_live_view, "~> 0.15.1"},
{:floki, ">= 0.27.0", only: :test},
{:phoenix_html, "~> 2.11"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:phoenix_live_dashboard, "~> 0.4.0"},
{:telemetry_metrics, "~> 0.4"},
{:telemetry_poller, "~> 0.4"},
{:gettext, "~> 0.11"},
{:jason, "~> 1.0"},
{:plug_cowboy, "~> 2.0"},

My Phoenix Version:

mix phx.new -v          
Phoenix v1.5.7

My dependencies:

{:phoenix, "~> 1.5.7"},
{:phoenix_ecto, "~> 4.1"},
{:ecto_sql, "~> 3.4"},
{:postgrex, ">= 0.0.0"},
{:phoenix_live_view, "~> 0.15.0"}, # here another differency
{:floki, ">= 0.27.0", only: :test},
{:phoenix_html, "~> 2.11"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:phoenix_live_dashboard, "~> 0.4"},
{:telemetry_metrics, "~> 0.4"},
{:telemetry_poller, "~> 0.4"},
{:gettext, "~> 0.11"},
{:jason, "~> 1.0"},
{:plug_cowboy, "~> 2.0"}

On page 19, has this definition of the WrongLive Module:

defmodule PentoWeb.WrongLive do
  use Phoenix.LiveView

and when I saw the definition of use LiveView on PageLive module, on my project, the way the definition it’s like this:

defmodule PentoWeb.PageLive do
  use PentoWeb, :live_view

Maybe this difference happened because of the between my phoenix version and the book.

Small typo on page 14 :

The module Phoenix.LiveView.Socket creates these stucts → structs

Cheers,

François

On page 22 : Finally, we return a tuple in the shape that LiveView expects—{:ok, socket}

Shouldn’t it be: {:noreply, socket} ?

1 Like

On mount function the tuple it is {:ok, socket}, an on others handle_* it is {:noreply, socket}

Thanks @herminiotorres and @froucoux! You’ll find all of these suggestions except for the question on dependency version addressed in the next Beta release :slight_smile: We appreciate your help in pointing these out :cupcake:

@herminiotorres in response to your question on different dependency versions being installed on your machine–that would be because you’re working with a later version of Phoenix than the one used when we wrote this code. Functionally, that doesn’t make a difference so I’ll leave the versions installed in the example alone for now. You can also check out page 13 where we specify that: “You might see a slightly different list [of dependencies installed] based on your version”. Hope that clears it up!

Thanks for answering my questions.

On page 42, when shows the piece of code to put phx.gen.auth into mix. exs file as a dependency.

auth/pento/mix.exs
{:phx_gen_auth, "~> 0.4"},

But when I saw the GitHub/doc related to this library, it basically tells about to define this dependency only for the dev environment.

auth/pento/mix.exs
{:phx_gen_auth, "~> 0.4", only: [:dev], runtime: false},

Thanks again @herminiotorres! You’ll find this updated in the next Beta release. To clarify a bit here, the only: [:dev], runtime: false config means that the phx_gen_auth library will only be installed in the development environment—it won’t be available in production, or at runtime of our application. This is because we only need to run the auth generator made available by this library in the development environment. The code it generates, however, will become part of our application and be available in all environments.

Hi! Enjoying this so far! Thanks for your work on it. Few typos and a suggestion:

  • p.75, Ch 1, §“Handle Events”: “Finally, we return a tuple in the shape that LiveView expects—{:ok, socket}.” For handle_event I think the tuple has to be {:no_reply, socket} or {:reply, socket}?
  • p.98, P 1 Ch 2, §“Reducers in Plug”: The second representation of the pipeline using pipe operators still has plug in the last three lines, but I think shouldn’t?
  • p.71, Ch 1, § “Render the Live View”: Just wondering, since the links you’re rendering go nowhere, if the semantics here aren’t better represented by <buttons>? And similarly the <h2> tag could be replaced by an ordered list? So:
<ol>
  <%= for n <- 1..10 do %>
    <li>
      <button phx-click="guess" phx-value-number="<%= n %>"><%= n %></button>
    </li>
  <% end %>
</ol>

Excited to keep reading!

Elixir 1.11.3, Firefox 86.0 and Safari Version 14.0.3 (16610.4.3.1.4). Followed the instructions on page 11 and I get the success page, but I see the following error message in my console being repeated over and over. My mix.exs is pasted below the error. I can’t see how it would be a problem with the instructions, they are pretty straightforward and I have generated other LiveView apps before without seeing this error…

[info] GET /
[debug] Processing with Phoenix.LiveView.Plug.index/2
  Parameters: %{}
  Pipelines: [:browser]
[info] Sent 200 in 3ms
[info] CONNECTED TO Phoenix.LiveView.Socket in 35µs
  Transport: :websocket
  Serializer: Phoenix.Socket.V2.JSONSerializer
  Parameters: %{"_csrf_token" => "WjEPKCEmAiVzCmgINjxHERJdLU8bUz8H0aWEfBLsCc00cY0Ef3cwo9p4", "vsn" => "2.0.0"}
[error] an exception was raised:
    ** (FunctionClauseError) no function clause matching in Phoenix.LiveView.Channel.start_link/1
        (phoenix_live_view 0.12.1) lib/phoenix_live_view/channel.ex:12: Phoenix.LiveView.Channel.start_link({PentoWeb.Endpoint, {#PID<0.577.0>, #Reference<0.935820641.833617927.145057>}})
        (elixir 1.11.3) lib/dynamic_supervisor.ex:693: DynamicSupervisor.start_child/3
        (elixir 1.11.3) lib/dynamic_supervisor.ex:679: DynamicSupervisor.handle_start_child/2
        (stdlib 3.13) gen_server.erl:706: :gen_server.try_handle_call/4
        (stdlib 3.13) gen_server.erl:735: :gen_server.handle_msg/6
        (stdlib 3.13) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

Here is my mix.exs:

defmodule Pento.MixProject do
  use Mix.Project

  def project do
    [
      app: :pento,
      version: "0.1.0",
      elixir: "~> 1.7",
      elixirc_paths: elixirc_paths(Mix.env()),
      compilers: [:phoenix, :gettext] ++ Mix.compilers(),
      start_permanent: Mix.env() == :prod,
      aliases: aliases(),
      deps: deps()
    ]
  end

  # Configuration for the OTP application.
  #
  # Type `mix help compile.app` for more information.
  def application do
    [
      mod: {Pento.Application, []},
      extra_applications: [:logger, :runtime_tools]
    ]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  # Specifies your project dependencies.
  #
  # Type `mix help deps` for examples and options.
  defp deps do
    [
      {:phoenix, "~> 1.5.0"},
      {:phoenix_ecto, "~> 4.1"},
      {:ecto_sql, "~> 3.4"},
      {:postgrex, ">= 0.0.0"},
      {:phoenix_live_view, "~> 0.12.0"},
      {:floki, ">= 0.0.0", only: :test},
      {:phoenix_html, "~> 2.11"},
      {:phoenix_live_reload, "~> 1.2", only: :dev},
      {:phoenix_live_dashboard, "~> 0.2.0"},
      {:telemetry_metrics, "~> 0.4"},
      {:telemetry_poller, "~> 0.4"},
      {:gettext, "~> 0.11"},
      {:jason, "~> 1.0"},
      {:plug_cowboy, "~> 2.0"}
    ]
  end

  # Aliases are shortcuts or tasks specific to the current project.
  # For example, to install project dependencies and perform other setup tasks, run:
  #
  #     $ mix setup
  #
  # See the documentation for `Mix` for more info on aliases.
  defp aliases do
    [
      setup: ["deps.get", "ecto.setup", "cmd npm install --prefix assets"],
      "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
      "ecto.reset": ["ecto.drop", "ecto.setup"],
      test: ["ecto.create --quiet", "ecto.migrate", "test"]
    ]
  end
end

you run this command:

mix phx.new pento --live

after that, you enter the pento folder project and create your data base and run the server? and didn’t work?

Not sure about this error in particular, but I just ran into a weird error with generated live view code I’ve never seen before, and I noticed the phoenix_live_view in mix.exs was old (0.13). I see yours is too. Try running mix hex.outdated, and probably mix deps.update phoenix_live_view and it’ll update the dashboard etc also. Not sure what’s up with my config that the generated phx app has outdated dependencies like this

p.75, Ch 1, §“Handle Events”: “Finally, we return a tuple in the shape that LiveView expects—{:ok, socket}.” For handle_event I think the tuple has to be {:no_reply, socket} or {:reply, socket}?

{:noreply, socket}

p.98, P 1 Ch 2, §“Reducers in Plug”: The second representation of the pipeline using pipe operators still has a plug in the last three lines, but I think shouldn’t?

I thinking I know what kind of example you talking about using the plug, and I think this part of the book it’s more like the way you need to see and think and not a correct code as the same in the phoenix generators at routes and endpoint files

p.71, Ch 1, § “Render the Live View”: Just wondering, since the links you’re rendering go nowhere, if the semantics here aren’t better represented by ? And similarly the

tag could be replaced by an ordered list? So:

IHMO, use the anchor link it’s okay because the most important thing it’s familiar with phx-* triggers this event and sent to the server.

Thanks for the pointer. I had to manually update the dependency versions in mix.exs, mix hex.outdated gave me what I pasted below. After I did that and ran mix deps.update --all it cleared up.

$ mix hex.outdated
Dependency              Current  Latest  Update possible
ecto_sql                3.5.4    3.5.4
floki                   0.30.0   0.30.0
gettext                 0.18.2   0.18.2
jason                   1.2.2    1.2.2
phoenix                 1.5.8    1.5.8
phoenix_ecto            4.2.1    4.2.1
phoenix_html            2.14.3   2.14.3
phoenix_live_dashboard  0.2.0    0.4.0   No
phoenix_live_reload     1.3.0    1.3.0
phoenix_live_view       0.12.1   0.15.4  No
plug_cowboy             2.4.1    2.4.1
postgrex                0.15.8   0.15.8
telemetry_metrics       0.4.2    0.6.0   No
telemetry_poller        0.5.1    0.5.1
1 Like

Hi there! Thanks for you feedback and questions :slight_smile:

  • p.75, Ch 1, §“Handle Events”: “Finally, we return a tuple in the shape that LiveView expects—{:ok, socket}.” For handle_event I think the tuple has to be {:no_reply, socket} or {:reply, socket}?

You are correct! You’ll find this updated in the next Beta release :cupcake:

  • p.98, P 1 Ch 2, §“Reducers in Plug”: The second representation of the pipeline using pipe operators still has plug in the last three lines, but I think shouldn’t?

Yes I think this example will be more clear with the change you are suggesting. You’ll find it in the next release!

p.71, Ch 1, § “Render the Live View”: Just wondering, since the links you’re rendering go nowhere, if the semantics here aren’t better represented by <buttons> ? And similarly the <h2> tag could be replaced by an ordered list?

Great suggestions and I think if I was building a “real” game, cleaning up the code in that way would be the way to go. But the current approach will suffice for this example :slight_smile:

1 Like

Hi, thanks for this lovely book! Here are some typo’s I ran into.

Page 51: Typo: double “the”: Then, we use the the context to check to see whether the user exists and has provided a valid password.

Page 60: “the not-uncommon skepticism of code generators.”.
I’m not native English speaking but should’t that be: “the not-uncommon skepticism about code generators.”?

Page 69: “Our changeset requires all of our attributes to be present.”
Suggestion: “Our changeset requires all of our attributes to be present, and the sku to be an unique value.

Page 72: " In this section, we’ll shift away from the core and into the places where the uncertain world intrudes on our beautiful assumptions.".
Should be something like: …and move into the places…, or …and wander into the places…

Page 92: " Here, it does so with the help of thelist_products() function"
Needs a space between the and list_products.

General suggestion: Use “we” throughout the book, there are still some places where singular is used. To bad I didn’t mark them. :frowning:

Thank you so much for helping by pointing these out! You’ll find most of the fixes applied in an upcoming Beta release. Not the next release, but probably the one after that :smiley: