jack

jack

So I was taking a look at documentation and other people code as well to understand a bit more about LiveView and specially, how to test it.

I’m still a bit confuse about some things, so those are probably very basic questions but I would appreciate any possible help, tip or advice.

Let’s take this example.

import Plug.Conn
import Phoenix.ConnTest
import Phoenix.LiveViewTest
@endpoint MyEndpoint

test "disconnected and connected mount", %{conn: conn} do
  conn = get(conn, "/my-path")
  assert html_response(conn, 200) =~ "<h1>My Disconnected View</h1>"

  {:ok, view, html} = live(conn)
end

We have this test for “disconnected and connected mount”.
I have a couple of questions about this.
The first one is what the endpoint tag purpose, I still didn’t found about it in the docs (I’m a bit in a hurry so I’m not reading it sequentially, maybe that’s why)

Now, I wonder why would I test “disconnected” and then “connected” mount in the same test case.
But before that, what really does a “disconnected mount” mean? I’ve been searching for this both on Google and on docs, but didn’t found any clarification about it.

As I understand the LiveView Life-Cycle so far is like this:

You receive a regular HTTP Request, it triggers mount/3, then handle_params/3, then render/1, and return a stateless, regular Web Page as HTTP Response.
Then, a WebSocket connection will start triggering mount/3 → handle_params/3 → render/1 again.

What a disconnected mount mean in this cycle?


Just like in this code example above, I’ve found people testing “disconnected mount” in their code as well.

assert html_response(conn, 200) =~ "<h1>My Disconnected View</h1>"

Like this code suggest, I saw people testing it like this: If I render a table, I would test the table empty instead.

My question is how?
If I use mount/3 or handle_params/3 to load the contents of my page, like executing a query to populate a table, how do so I could test for an “empty table” if I’m receiving a page after the complete life-cycle?

Right now I’m prototyping an application to learn and practice LiveView, I have the table as LiveComponents, do I could test successfully passing one valid list to the live component with render_component/2 and asserting the result. This is because I can control the params received in a live component, so I can test it and assert that only one <td> was created if I only passed one element in the list as params.

But if I use the mount/3 function to fetch data testing the liveview page instead of an isolated component, I’ll not be able to ever see this table empty.
Isn’t that what I’m supposed to do? Isn’t mount/3 where I fetch data to prepare the page for the response?

So, what a “disconnected mount” means, and what is the difference to a connected mount?
Can I receive the HTTP response after mount/3 but before handle_params/3?
Can I have a mount/3 for the HTTP response and another mount/3 that will execute only after the WebSocket being stablished?
(Like not fetching data from database in the HTTP request but fetching after a Live Socket start?)

Additionally how can I, in a test, force a failed connection to the database?

Sorry, those are a lot of questions, but I’m still a bit lost about how to test things both on Phoenix as a whole but specially about LiveView. I was wondering for a good bit why people wasn’t using controllers but doing everything on LiveView for example, so is the LiveView supposed to be both Controller, View and Template?
(and possible all three in the same file since you can render a sigil/literal instead of creating a separate template…)

I’m having a lot of fun learning LiveView but I’m not sure on how to do it “right”, I mean, in an organised and well designed way.
Should I call my (context/model) functions directly from LiveView? Or is it a better design to create a Controller, call the Controller from the LiveView, and then this Controller will interact with the Context?
This is not how I’m seeing people use it but I thought that LiveView would only be another type of “View”, I was surprised about it acting as a Controller in a lot of code I’m consuming to learn from.

Thank you for taking your time to read this until the end.

Showing Posts 1 to 2

cmo

cmo

First mount is disconnected which creates the websocket connection, rest of it happens over websocket (until you redirect etc). You can call connected?(socket) and it will be false for the first mount. You can setup a page with loading placeholders for things here if you like, which will populate either on the connected mount or you could send(self(), {:load_some_thing, ...}) in the mount so you can load the page first or you can do it async and send a message back to the liveview to assign it later.

Should I call my context/module from the LiveView?

Yep. You don’t need much in the way of controllers if your site is all live views. I don’t think of my project in terms of Models, Controllers and Views. I just build a UI in LiveView and call functions in modules :slight_smile:.

To learn about the lifecycle, you might like to watch this talk

This course might be of use to you. They go through the lifecycle and more.

jack

jack OP

Thank you for taking your time to reply cmo!

Your explanation was very helpful, honestly I understood what a disconnect mount is for your reply only.
The docs was not very clear for me, and the talk… I had watched it before and just watch it a second time right now and although it’s entertaining, for someone who is already confused about it showing non-working code it’s not really helpful. I liked the talk and I learned some things but not really about the life cycle itself… :sweat_smile:

I will take a look at the course, thank you!

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews