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

dimitarvp
As a part of my new job I’ll have to learn to manage a local k8s cluster. The tools used are microk8s, tilt and helm. I’ll appreciate an...
New
andrea
Can Phoenix LiveView be used in multi-page applications, unlike React/Vue/Blazor which seems to be targeted for SPA?
New
joshi
Hey everybody! I’m working on the project that includes import of Oracle data to PostgreSQL. That data comes as Oracle export (expdp) fi...
New
Jsdr3398
I’ve been working on and rewriting my messaging platform several times for the past two years. With Discords new rebranding, it has reall...
New
s2k
I have this code in a file that’s used to … render templates. require 'erb' require 'ostruct' MISSING_CONFIG_MARKER = :config_key_and_v...
New
Fl4m3Ph03n1x
Background I have recently been delving into more functional code. My objective right now is to get something similar to the IO Monad (in...
New
Fl4m3Ph03n1x
Background I am a fan of dialyzer and friends (looking at Gradient) and I try to have sepcs in my code as much as I can. To this end, I a...
New
sona11
I studied very basic PHP (I believe). After that, I feel like I’ve gotten a handle on the language. My dream is to work as a web develope...
New
harwind
I have a large SQL database with millions of records, and I’ve identified duplicate entries. What’s the most efficient way to find and re...
New
Fl4m3Ph03n1x
Background I have an umbrella app where I use a dependecy called ETS. This dependency has a type called set_options that I use in some of...
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
siddhant3030
I’m thinking of buying a monitor that I can rotate to use as a vertical monitor? Also, I want to know if someone is using it for program...
New
AstonJ
SpaceVim seems to be gaining in features and popularity and I just wondered how it compares with SpaceMacs in 2020 - anyone have any thou...
New
AstonJ
There’s a whole world of custom keycaps out there that I didn’t know existed! Check out all of our Keycaps threads here: https://forum....
New
AstonJ
If you are experiencing Rails console using 100% CPU on your dev machine, then updating your development and test gems might fix the issu...
New
Help
I am trying to crate a game for the Nintendo switch, I wanted to use Java as I am comfortable with that programming language. Can you use...
New
AstonJ
If you want a quick and easy way to block any website on your Mac using Little Snitch simply… File &gt; New Rule: And select Deny, O...
New
PragmaticBookshelf
Develop, deploy, and debug BEAM applications using BEAMOps: a new paradigm that focuses on scalability, fault tolerance, and owning each ...
New
AnfaengerAlex
Hello, I’m a beginner in Android development and I’m facing an issue with my project setup. In my build.gradle.kts file, I have the foll...
New
mindriot
Ok, well here are some thoughts and opinions on some of the ergonomic keyboards I have, I guess like mini review of each that I use enoug...
New