Open j-n-f opened 2 hours ago
Just piggybacking here:
This is fine when the template is small like in this counter, but in a bigger App like our MPV it's a good idea to split the template into a separate file to make it easier to read and maintain.
I think MPV
is a typo.
Another oddity:
def render(assigns) do
~H"""
<div class="text-center">
<h1 class="text-4xl font-bold text-center"> Counter: <%= @val %> </h1>
<.button phx-click="dec" class="w-20 bg-red-500 hover:bg-red-600">-</.button>
<.button phx-click="inc" class="w-20 bg-green-500 hover:bg-green-600">+</.button>
</div>
"""
end
Initial example shows <.button ...>
but later (when the template goes in its own file):
def render(assigns) do
~H"""
<div class="text-center">
<h1 class="text-4xl font-bold text-center"> Counter: <%= @val %> </h1>
<button phx-click="dec" class={btn("red")}>
-
</button>
<button phx-click="inc" class={btn("green")}>
+
</button>
</div>
"""
end
The .
prefix disappears. No explanation is given.
I think most people will find the .
prefix most surprising, so maybe a little explanation can be given for what that means after showing it the first time, or at least mention that it will be explained later.
Finally, we need make some changes to the LiveView itself, it now has less to do!
defmodule CounterWeb.Counter do
use CounterWeb, :live_view
alias Counter.Count
alias Phoenix.PubSub
@topic Count.topic
def mount(_params, _session, socket) do
if connected?(socket) do
# why are we using Counter.PubSub?
# vvvvvvvvvvvvvv this is aliased the same as Phoenix.PubSub
PubSub.subscribe(Counter.PubSub, @topic)
end
{:ok, assign(socket, val: Count.current()) }
end
# ...
end
This bit also doesn't make sense. I know that Counter.PubSub
could be something completely different, but it really does look like it references the same thing.
Create a file with the path: lib/counter_web/live/counter_state.ex and add the following:
def handle_call(:current, _from, count) do
{:reply, count, count}
end
defp make_change(count, change) do
new_count = count + change
PubSub.broadcast(Counter.PubSub, topic(), {:count, new_count})
{:reply, new_count, new_count}
end
Why is the count value returned twice in these functions?
What is Counter.PubSub
? The module is called Counter.Count
. I don't see where Counter.PubSub
is defined. I'm guessing alias Phoenix.PubSub
would be fully qualified in this scope as Counter.Count.PubSub
so it wouldn't be referring to that. It's not anywhere in counter.ex
.
edit: found it: https://github.com/dwyl/phoenix-liveview-counter-tutorial/blob/main/lib/counter/application.ex#L16
I don't think the application.ex
was covered.application.ex
is mentioned in passing, but it seems like an important element of how the framework functions. It might be nice to have it explained, what it does, how it relates to other things, where/if it has to be registered anywhere else in the application, etc. At a minimum, maybe something like "you can read about what this file is and what it does at ".
Some of these could be considered more general bits of Elixir trivia (namespacing, etc.).
I think with the earlier claim:
Basic familiarity with Elixir syntax is recommended but not essential
It's looking to me like it probably is essential. Maybe there are ways to gently fold (some of) these bits of knowledge into the tutorial.
And that's all I've got for now.
It's a massive effort to mix together this amount of prose and code and I appreciate all the work you've put into it.
One thing that impressed me lately is the format of the Svelte tutorial. I don't know if there's an interactive tool like this for Elixir, but I could see the content in this tutorial fitting that kind of format really nicely. I did a little search, but so far I don't see anything that would run the BEAM in wasm or something like that, but it would be really cool if it did.
Total elixir newbie here (so my ignorance is pretty high, but maybe this is a useful perspective).
I think for people coming from other languages/frameworks it's a bit confusing to mention that the key is
"inc"
. I don't see that key pop up anywhere else after that, or see how the"inc"
value is relevant. It looks like the new state of:val
is already set and sent to the topic. Is it going to callhandle_event("inc", ...)
again? It doesn't look like it, it seems likehandle_info(...)
is going to updateassigns
for all the connected clients.To put the question another way, why should I pass
"inc"
instead of"foo"
?Everything else is clear, but that's the one bit that doesn't make sense.