User: Admin: Difference between revisions
No edit summary |
No edit summary |
||
Line 9: | Line 9: | ||
<li><btn id="btn3Label" data-toggle="tab" class="nav-link" role="tab" aria-controls="tab3" aria-selected="false">#tab2|CREATE LIVEVIEWS</btn></li> | <li><btn id="btn3Label" data-toggle="tab" class="nav-link" role="tab" aria-controls="tab3" aria-selected="false">#tab2|CREATE LIVEVIEWS</btn></li> | ||
<li><btn id="btn4Label" data-toggle="tab" class="nav-link" role="tab" aria-controls="tab4" aria-selected="false">#tab2|EDIT LIVEVIEWS</btn></li> | <li><btn id="btn4Label" data-toggle="tab" class="nav-link" role="tab" aria-controls="tab4" aria-selected="false">#tab2|EDIT LIVEVIEWS</btn></li> | ||
<li><btn id="btn5Label" data-toggle="tab" class="nav-link" role="tab" aria-controls="tab5" aria-selected="false">#tab2|SUBSCRIBE</btn></li> | <li><btn id="btn5Label" data-toggle="tab" class="nav-link" role="tab" aria-controls="tab5" aria-selected="false">#tab2|SUBSCRIBE|BROADCAST|HANDLE_INFO</btn></li> | ||
</ul> | </ul> |
Revision as of 16:32, 17 June 2023
Tab 1: Lorem ipsum...
scope "/", AppWeb do pipe_through :browser live "/send", SendLive, :home live "/receive", ReceiveLive, :home end
Create two working minimalistic LiveViews.
One is named SendView and the other is ReceiveView .
The SendView consist of a single form field to send data to RecieveView. ReceiveView contains code to renders SendView data to its page.
To understand web socket configuration we will:
1. Create a one way data connection between the two LiveViews and explain clearly the relationship between the code pieces with a focus on data flow.
2. Edit the code to create a two-way connection between both live views.
3. Combine both LiveViews into one live view to send and receive.
4. Write code to store real time chat content to a database.
This may seem like pointless overkill and maybe it is. However, this is what has worked for me.
PUB SUB
Before we begin, I will share three small pieces of code with you. These are the main characters, or main components for what we will build.
AppWeb.Endpoint.subscribe()
AppWeb.Endpoint.broadcast()
def handle_info(msg, socket) do {:noreply, assign(socket)} end
def handle_event(msg, params, socket) do {:noreply, socket} end
We will ultimately weave these little pieces of code into a LiveView and create a chat application.
Create Two Minimalistic Vanilla LiveViews
In router.ex create the following routes:
scope "/", AppWeb do pipe_through :browser live "/send", SendLive, :home live "/receive", ReceiveLive, :home end
In app_web create a folder named live. In the live folder create a file named send_live.ex.
Copy this code into it:
defmodule AppWeb.SendLive do use AppWeb, :live_view def mount(_params, _session, socket) do {:ok, assign(socket, data: " ")} end def handle_event("send", params, socket) do {:noreply, socket} end def render(assigns) do ~H""" <div> <h1>connection Send</h1> <form phx-submit="send"> <input type="text" name="text" /> <button type="submit">Send</button> </form> </div> """ end end
defmodule AppWeb.SendLive do use AppWeb, :live_view def mount(_params, _session, socket) do if connected?(socket) do end {:ok, assign(socket, username: username, messages: [])} end # def handle_info(%{event: "message", payload: message}, socket) do # {:noreply, assign(socket, messages: socket.assigns.messages ++ [message])} # end def handle_event("send", %{"text" => text}, socket) do AppWeb.Endpoint.broadcast("connection input-1", "SOUND", %{ text: text, name: socket.assigns.username }) {:noreply, socket} end defp username do "User #{:rand.uniform(100)}" end def render(assigns) do ~H""" <div> <h1>connection Send</h1> <div class="messages" style="border: 1px solid #eee; height: 400px; overflow: scroll; margin-bottom: 8px;" > </div> <form phx-submit="send"> <input type="text" name="text" /> <button type="submit">Send</button> </form> </div> """ end end
defmodule AppWeb.ReceiveLive do use AppWeb, :live_view def mount(_params, _session, socket) do {:ok, assign(socket, messages: " ")} end def handle_info(msg, socket) do {:noreply, assign(socket, data: "")} end def render(assigns) do ~H""" <div> <h1>ReceiveLive Connection</h1> <%= for m <- [1,2,3,4,5] do %> <%= m %> <% end %> </div> """ end end
defmodule AppWeb.RecieveLive do use AppWeb, :live_view def mount(_params, _session, socket) do if connected?(socket) do AppWeb.Endpoint.subscribe("connection input-1") end {:ok, assign(socket, username: username, messages: [])} end def handle_info(%{event: "SOUND", payload: message}, socket) do {:noreply, assign(socket, messages: socket.assigns.messages ++ [message])} end # def handle_event("send", %{"text" => text}, socket) do # AppWeb.Endpoint.broadcast("connection input-1", "message", %{ # text: text, # name: "X" # }) # {:noreply, socket} # end defp username do "User #{:rand.uniform(100)}" end def render(assigns) do ~H""" <div> <h1>connection Recieve Live</h1> <div class="messages" style="border: 1px solid #eee; height: 400px; overflow: scroll; margin-bottom: 8px;" > <%= for m <- @messages do %> <p style="margin: 2px;"><b><%= m.name %></b>: <%= m.text %></p> <% end %> </div> </div> """ end end
Open the /send route and the /receive route each in their own tab. You will now write code so the form in send sends data to the page in receive.
- How to Create Database Seed Data.
- How to Use Generators in a Real World Project
- How to Work with Database Data via Basic Commands and Custom Change sets.
- How to Render Database Data to LiveView (via Context Commands).
- How to Create a Chat using PubSub.
- How to Create Event Handlers in LiveView
- How to Create a Dynamic Route from Scratch.
- How to Use Elixirs Template language
- How to Work with Modal
- How to Use CSS From Scratch (Without bundler)
- How to use JS hooks
_________________________________________________
https://elixirschool.com/blog/live-view-live-component
Note:
mix phx.gen.html Alerts Alert alerts title:string content:text enabled:boolean
defmodule AppWeb.PageLive do use AppWeb, :live_view alias App.Alerts def mount(_params, _session, socket) do {:ok, assign(socket, alerts: Alerts.list_alerts())} end def render(assigns) do ~H""" <%= for alert <- @alerts do %> <%= if alert.enabled do %> <div><%= alert.content%></div> <% end %> <% end %> """ end end #_____________________________ def check_for_single_selection(data) do list = App.Alerts.list_alerts() IO.inspect list result = Enum.filter(list, fn x -> x.enabled == true end) IO.inspect "WORK_____________________________" IO.inspect result IO.inspect "WORK_____________________________" data end
__________________________________________________
Complex pattern matching https://www.youtube.com/watch?v=gCVWrM5BNVE
Genservers (and related, agent,task etc)
__________________________________________________
ECTO
query = from "artists", select:[:name]
Verbose:
Ecto.Query.from("artists", select[:name])
Repo.all(query)
- => [%{name: "Miles Davis"}, %{name: "Bill Evans"}]
Repo.to_sql(:all, query)