Reputation: 16271
In my Phoenix/Elixir boilerplate web app I have the typical structure described here, where the simple HelloController
uses a HelloView component to render the templates in the hello/
folder. This works ok.
Now let's say I want to add the snake_view.ex
View component here. This View depends on Phoenix
LiveView and acts slightly different than other ordinary views, that render templates, since it has a render
method in it among the other functions:
defmodule HelloWeb.SnakeView do
use Phoenix.LiveView
# ..
def render(%{game_state: :over} = assigns) do
# ..
Now, after adding the LiveView
dependency, I have added a route in router.ex
get "/snake", SnakeController, :index
But now I do not know how to reference the SnakeView
from this new SnakeController
:
defmodule HelloWeb.SnakeController do
use HelloWeb, :controller
def index(conn, _params) do
render(conn)
end
end
The error I get when heading to http://localhost:4000/snake is
function HelloWeb.SnakeView.render/2 is undefined or private
so it seems that from the router the SnakeController
has been invoked, and the SnakeView
as well, but something is wrong.
[UPDATE]
I have realized that there were a lot of things I was missing to do before make it working the Phoenix LiveView
within the PhoenixFramework WebApp:
Endpoint endpoint.ex
. You need to add a
socket "/live", Phoenix.LiveView.Socket
Router router.ex
. Add a route to the LiveView
via the PageController
:
get "/snake", PageController, :snake
In the PageController
add a def for the snake
function:
def snake(conn, _) do
conn
|> put_layout(:game)
|> LiveView.Controller.live_render(HelloWeb.SnakeLive, session: %{})
end
WebApp your_app_web.ex
. Add in view
def the
import Phoenix.LiveView, only: [live_render: 2, live_render: 3]
Config in configs.exs
. Add a LiveView
salt token:
live_view: [
signing_salt: "YOUR_LIVEVIEW_TOKEN"
]
Add a live
folder in your your_app_web
web app folder. Put your LiveView
view there.
Add the WebSocket connection in the main app.js
file:
import {LiveSocket, debug} from "phoenix_live_view"
let liveSocket = new LiveSocket("/live")
liveSocket.connect()
Added css resources: live_view.css
, snake.css
, imported in app.css
the new css:
@import "./phoenix.css";
@import "./live_view.css";
@import "./snake.css";
The resulting WebApp structure should now be:
├── assets
│ ├── css
│ │ ├── app.css
│ │ ├── live_view.css
│ │ ├── phoenix.css
│ │ └── snake.css
│ ├── js
│ │ ├── app.js
│ │ └── socket.js
├── config
│ ├── config.exs
├── lib
│ ├── hello
│ │ └── application.ex
│ ├── hello.ex
│ ├── hello_web
│ │ ├── channels
│ │ ├── controllers
│ │ ├── endpoint.ex
│ │ ├── gettext.ex
│ │ ├── live
│ │ ├── router.ex
│ │ ├── templates
│ │ └── views
│ └── hello_web.ex
At this stage, when pointing the browser to http://localhost:4000/snake I get the LiveView partially working:
Please check the full code here to investigate this issue.
Upvotes: 1
Views: 2523
Reputation: 600
At the bottom of this page - https://github.com/phoenixframework/phoenix_live_view - there's at least one step that I'm not seeing in your code.
// assets/js/app.js
import LiveSocket from "phoenix_live_view"
let liveSocket = new LiveSocket("/live")
liveSocket.connect()
Perhaps add that and confirm that you have the rest of the steps covered as well. Hopefully that works :)
Upvotes: 2