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

chasekaylee
Hi there everyone! Recently, I have fallen in love with programming with Elixir and have been having so much fun with it. I have been do...
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
New
JimmyCarterSon
I am confused about the Schema setup, I am setting up a new application and I want to seed files in it as well. I tried to mix to create...
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
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
Fl4m3Ph03n1x
Background I have to queries that return a colossal amount of data on their own. I cannot use Repo.all as doing so would materialize thes...
New
Fl4m3Ph03n1x
Background I have a module that uses TypedStruct to create structs. This is the code: defmodule Shared.Data.Authorization do @moduledo...
New
ogoldberg
Any recommendations on good resources for learning Elixir, Phoenix, and Ash?
New

Other popular topics Top

New
PragmaticBookshelf
Machine learning can be intimidating, with its reliance on math and algorithms that most programmers don't encounter in their regular wor...
New
AstonJ
poll poll Be sure to check out @Dusty’s article posted here: An Introduction to Alternative Keyboard Layouts It’s one of the best write-...
New
AstonJ
Thanks to @foxtrottwist’s and @Tomas’s posts in this thread: Poll: Which code editor do you use? I bought Onivim! :nerd_face: https://on...
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
AstonJ
I ended up cancelling my Moonlander order as I think it’s just going to be a bit too bulky for me. I think the Planck and the Preonic (o...
New
PragmaticBookshelf
Build highly interactive applications without ever leaving Elixir, the way the experts do. Let LiveView take care of performance, scalabi...
New
AstonJ
If you get Can't find emacs in your PATH when trying to install Doom Emacs on your Mac you… just… need to install Emacs first! :lol: bre...
New
New
AstonJ
This is a very quick guide, you just need to: Download LM Studio: https://lmstudio.ai/ Click on search Type DeepSeek, then select the o...
New