pillaiindu

pillaiindu

What's wrong with my Phoenix LiveView code?

Currently reading the book “Programming Phoenix LiveView”.
At the end of the Chapter 1, I’m trying to solve the guess game. If the user guesses the random number generated by the program the program should say Your guess: #{guess}. Correct!, but it doesn’t run that condition even if the guessed number is exactly the same as the random_number generated at the time of mount.
I’ve also added the line The randome number is <%= @random %> to see if I’m guessing the correct number.

Following is the code.

defmodule PentoWeb.WrongLive do
  use PentoWeb, :live_view

  def mount(_params, _session, socket) do
    {:ok, assign(socket, score: 0, message: "Make a guess:", time: time(), random: random())}
  end

  def render(assigns) do
    ~H"""
    <h1 class="mb-4 text-4xl font-extrabold">Your score: <%= @score %></h1>
    <h2>
      <%= @message %>
      The randome number is <%= @random %>
    </h2>
    <br/>
    <h2>
      <%= for n <- 1..10 do %>
        <.link class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 border border-blue-700 rounded m-1" phx-click="guess" phx-value-number= {n} >
          <%= n %>
        </.link>
      <% end %>
    </h2>
    """
  end

  def time() do
    DateTime.utc_now() |> to_string()
  end

  def random() do
    Enum.random(1..10)
  end

  def handle_event("guess", %{"number" => guess}, socket) do
    message = cond do
      guess == socket.assigns.random ->
        "Your guess: #{guess}. Correct!"
      true ->
        "Your guess: #{guess}. Wrong. Guess again."
    end

    {:noreply, assign(socket, score: socket.assigns.score + 1, message: message, time: time(), random: socket.assigns.random)}
  end
end

@SophieDeBenedetto

Most Liked

zimt28

zimt28

Your guess variable in the handle_event function is a string, so guess == socket.assigns.random is comparing a string against an integer. An easy fix would be to return a string from your random/0 function.

pillaiindu

pillaiindu

Bard said to make the handle_event like this,

  def handle_event("guess", %{"number" => guess}, socket) do
    message = cond do
      guess == socket.assigns.random ->
        "Your guess: #{guess}. Correct!"
        {:noreply, assign(socket, random: random())}
      true ->
        "Your guess: #{guess}. Wrong. Guess again."
    end

      {:noreply, assign(socket, score: socket.assigns.score + 1, message: message, time: time())}
    end

but that didn’t work either.

pillaiindu

pillaiindu

Thank you for your reply!

It doesn’t work. I tried converting the value inside random() function to String, it didn’t work that way.
Then I converted the guess coming from the user inside the handle_event to integer before comparing it with socket.assign.random, it didn’t work again.

Right now my code is as follows,

defmodule PentoWeb.WrongLive do
  use PentoWeb, :live_view

  def mount(_params, _session, socket) do
    {:ok, assign(socket, score: 0, message: "Make a guess:", time: time(), random: random())}
  end

  def render(assigns) do
    ~H"""
    <h1 class="mb-4 text-4xl font-extrabold">Your score: <%= @score %></h1>
    <h2>
      <%= @message %>
      The randome number is <%= @random %>
    </h2>
    <br/>
    <h2>
      <%= for n <- 1..10 do %>
        <.link class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 border border-blue-700 rounded m-1" phx-click="guess" phx-value-number= {n} >
          <%= n %>
        </.link>
      <% end %>
    </h2>
    """
  end

  def time() do
    DateTime.utc_now()
  end

  def random() do
    Enum.random(1..10)
  end

  def handle_event("guess", %{"number" => guess}, socket) do
    guess = Integer.parse(guess) |> elem(0)
    message = cond do
      guess == socket.assigns.random ->
        "Your guess: #{guess}. Correct!"
        {:noreply, assign(socket, random: random())}
      true ->
        "Your guess: #{guess}. Wrong. Guess again."
    end

      {:noreply, assign(socket, score: socket.assigns.score + 1, message: message, time: time())}
    end
  end

At this point when I click the correct option, it gives the following error,

[debug] HANDLE EVENT "guess" in PentoWeb.WrongLive
  Parameters: %{"number" => "3"}
[debug] Replied in 729µs
[error] GenServer #PID<0.505.0> terminating
** (Protocol.UndefinedError) protocol Phoenix.HTML.Safe not implemented for {:noreply, #Phoenix.LiveView.Socket<id: "phx-F5RYrXnIuZbLRwBE", endpoint: PentoWeb.Endpoint, view: PentoWeb.WrongLive, parent_pid: nil, root_pid: #PID<0.505.0>, router: PentoWeb.Router, assigns: %{message: "Make a guess:", time: ~U[2023-11-04 06:49:57.476986Z], random: 2, __changed__: %{random: true}, flash: %{}, live_action: nil, score: 0}, transport_pid: #PID<0.497.0>, ...>} of type Tuple. This protocol is implemented for the following type(s): Atom, BitString, Date, DateTime, Decimal, Float, Integer, List, NaiveDateTime, Phoenix.HTML.Form, Phoenix.LiveComponent.CID, Phoenix.LiveView.Component, Phoenix.LiveView.Comprehension, Phoenix.LiveView.JS, Phoenix.LiveView.Rendered, Time, Tuple, URI
    (phoenix_html 3.3.3) lib/phoenix_html/safe.ex:97: Phoenix.HTML.Safe.Tuple.to_iodata/1
    (pento 0.1.0) lib/pento_web/live/wrong_live.ex:12: anonymous fn/2 in PentoWeb.WrongLive.render/1
    (phoenix_live_view 0.19.5) lib/phoenix_live_view/diff.ex:363: Phoenix.LiveView.Diff.traverse/7
    (phoenix_live_view 0.19.5) lib/phoenix_live_view/diff.ex:538: anonymous fn/4 in Phoenix.LiveView.Diff.traverse_dynamic/7
    (elixir 1.15.7) lib/enum.ex:2510: Enum."-reduce/3-lists^foldl/2-0-"/3
    (phoenix_live_view 0.19.5) lib/phoenix_live_view/diff.ex:361: Phoenix.LiveView.Diff.traverse/7
    (phoenix_live_view 0.19.5) lib/phoenix_live_view/diff.ex:136: Phoenix.LiveView.Diff.render/3
    (phoenix_live_view 0.19.5) lib/phoenix_live_view/channel.ex:833: Phoenix.LiveView.Channel.render_diff/3
    (phoenix_live_view 0.19.5) lib/phoenix_live_view/channel.ex:689: Phoenix.LiveView.Channel.handle_changed/4
    (stdlib 5.1.1) gen_server.erl:1077: :gen_server.try_handle_info/3
    (stdlib 5.1.1) gen_server.erl:1165: :gen_server.handle_msg/6
    (stdlib 5.1.1) proc_lib.erl:251: :proc_lib.wake_up/3
Last message: %Phoenix.Socket.Message{topic: "lv:phx-F5RYrXnIuZbLRwBE", event: "event", payload: %{"event" => "guess", "type" => "click", "value" => %{"number" => "3"}}, ref: "13", join_ref: "11"}
State: %{socket: #Phoenix.LiveView.Socket<id: "phx-F5RYrXnIuZbLRwBE", endpoint: PentoWeb.Endpoint, view: PentoWeb.WrongLive, parent_pid: nil, root_pid: #PID<0.505.0>, router: PentoWeb.Router, assigns: %{message: "Make a guess:", time: ~U[2023-11-04 06:49:57.476986Z], random: 3, __changed__: %{}, flash: %{}, live_action: nil, score: 0}, transport_pid: #PID<0.497.0>, ...>, components: {%{}, %{}, 1}, topic: "lv:phx-F5RYrXnIuZbLRwBE", serializer: Phoenix.Socket.V2.JSONSerializer, join_ref: "11", upload_names: %{}, upload_pids: %{}}
[debug] MOUNT PentoWeb.WrongLive
  Parameters: %{}
  Session: %{"_csrf_token" => "-UTX1GiHNYDm90jd4qqktPfh"}
[debug] Replied in 104µs

Where Next?

Popular Backend topics Top

DevotionGeo
I know that -t flag is used along with -i flag for getting an interactive shell. But I cannot digest what the man page for docker run com...
New
AstonJ
Just done a fresh install of macOS Big Sur and on installing Erlang I am getting: asdf install erlang 23.1.2 Configure failed. checking ...
New
dimitarvp
Hey everyone, I resumed work on my Elixir &lt;=&gt; SQLite library (which uses a Rust NIF underneath) and I am in a need of small and we...
New
andrea
Can Phoenix LiveView be used in multi-page applications, unlike React/Vue/Blazor which seems to be targeted for SPA?
New
sampu
I have a use case where a client is invoking a Rest endpoint via a load balancer, which in turn invokes a third party endpoint which is r...
New
GermaVinsmoke
Does anyone know beginner friendly Elixir/Phoenix Open source projects? For learning purpose :slightly_smiling_face:
New
AstonJ
If when trying to create (or recreate) your dev db with rails db:create you are getting: PG::ConnectionBad: connection to server on soc...
New
Fl4m3Ph03n1x
Background I have a module that uses TypedStruct to create structs. This is the code: defmodule Shared.Data.Authorization do @moduledo...
New
Sumityadav
Hello all, I am new to learning Java Programming and want to learn java from scratch. I was writing a Java program to get the first and l...
New
jaeyson
Hi! I have clarifications (please correct me, as I mostly mix/confuse this details) with the following: The term RAG here where it read...
New

Other popular topics Top

PragmaticBookshelf
Learn from the award-winning programming series that inspired the Elixir language, and go on a step-by-step journey through the most impo...
New
AstonJ
What chair do you have while working… and why? Is there a ‘best’ type of chair or working position for developers?
New
AstonJ
Or looking forward to? :nerd_face:
490 12945 266
New
PragmaticBookshelf
Design and develop sophisticated 2D games that are as much fun to make as they are to play. From particle effects and pathfinding to soci...
New
AstonJ
I’ve been hearing quite a lot of comments relating to the sound of a keyboard, with one of the most desirable of these called ‘thock’, he...
New
PragmaticBookshelf
Rust is an exciting new programming language combining the power of C with memory safety, fearless concurrency, and productivity boosters...
New
Exadra37
I am asking for any distro that only has the bare-bones to be able to get a shell in the server and then just install the packages as we ...
New
Margaret
Hello everyone! This thread is to tell you about what authors from The Pragmatic Bookshelf are writing on Medium.
1147 29994 760
New
husaindevelop
Inside our android webview app, we are trying to paste the copied content from another app eg (notes) using navigator.clipboard.readtext ...
New
PragmaticBookshelf
Get the comprehensive, insider information you need for Rails 8 with the new edition of this award-winning classic. Sam Ruby @rubys ...
New