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

New
Kurisu
Hello and happy new year! I would like to buy a Ruby On Rails ebook for learning purpose. What would be the ROR equivalent of “Programm...
New
GermaVinsmoke
Reading Programming Elixir 1.6 book, I’ve completed part 1 of the book. Now I’m thinking of reading Elixir in Action. What do you all sug...
New
bsek43
Hello everyone, I’ve started learning Elixir and Phoenix few months ago and while I mostly grasped Elixir’s functional concepts and Phoe...
New
Fl4m3Ph03n1x
Background I am now trying Gradual type checking, as a consequence I am giving a shot to Gradient. As I see it, this is an alternative to...
New
Ora2pgnewbie
Wanted to check if there is a UI available to use Ora2pg tool.
New
Manish_bose
Can anyone help me how to convert a long data to wide data in SQL without using hard coding? Regards Manish
New
sona11
If isReachable throws an IOException in Java, what is the right step to do and why? The application, I believe, should halt the process ...
New
pillaiindu
What is the difference between using :references and :belongs_to in the following command? bin/rails generate scaffold LineItem product:...
New
Shiny
Hey community, this is my first post here so I will try to be as concise as possible and I appreciate any feedback. I’ve been writing Ro...
New

Other popular topics Top

ohm
Which, if any, games do you play? On what platform? I just bought (and completed) Minecraft Dungeons for my Nintendo Switch. Other than ...
New
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
Curious to know which languages and frameworks you’re all thinking about learning next :upside_down_face: Perhaps if there’s enough peop...
New
New
AstonJ
Saw this on TikTok of all places! :lol: Anyone heard of them before? Lite:
New
PragmaticBookshelf
Author Spotlight Jamis Buck @jamis This month, we have the pleasure of spotlighting author Jamis Buck, who has written Mazes for Prog...
New
PragmaticBookshelf
Programming Ruby is the most complete book on Ruby, covering both the language itself and the standard library as well as commonly used t...
New
PragmaticBookshelf
Author Spotlight: Karl Stolley @karlstolley Logic! Rhetoric! Prag! Wow, what a combination. In this spotlight, we sit down with Karl ...
New
DevotionGeo
I have always used antique keyboards like Cherry MX 1800 or Cherry MX 8100 and almost always have modified the switches in some way, like...
New
PragmaticBookshelf
Author Spotlight: Peter Ullrich @PJUllrich Data is at the core of every business, but it is useless if nobody can access and analyze ...
New