lcabrini
Conditionally showing "delete" link in index live views
I have a schema with a status field, that can be :draft, :published, etc. In the index live view, I only want the delete link to be available for items that have not been published, that is they are :draft.
I thought this should be extremely simple:
<%= if article.status == :draft do %>
<:action :let={{id, article}}>
<.link
phx-click={JS.push("delete", value: %{id: article.id}) |> hide("##{id}")}
data-confirm="Are you sure?"
>
Delete
</.link>
</:action>
<% end %>
However, this tells me:
== Compilation error in file lib/foobar_web/live/article_live/index.ex ==
** (Phoenix.LiveView.Tokenizer.ParseError) lib/foobar_web/article_live/index.ex:37:11: invalid slot entry <:action>. A slot entry must be a direct child of a component
|
34 | Delete
35 | </.link>
36 | </:action>
37 | <% end %>
| ^
I don’t really get it. As far as I understand, it IS a direct child of a component, all that exists above it is a logic statement, a “preprocessor statement”, which should have been evaluated in an initial pass, or?
In any case, I accept that for some reason this doesn’t work.. But then, how would I achieve what I’m trying to do? It seems common enough that I imagine this should be easy to do. I can’t seem to find the right keywords to search on.
If I re-arrange it a bit so that the <% if … %> is embedded inside the <:action …>, then it does work. Is that the best way to do it?
Marked As Solved
LostKobrakai
<:action :let={{id, article}}>
<.link
:if={article.status == :draft}
phx-click={JS.push("delete", value: %{id: article.id}) |> hide("##{id}")}
data-confirm="Are you sure?"
>
Delete
</.link>
</:action>
This would be the option to render the slot, but not the link within the slot.
Also Liked
matt-savvy
What happens if you do it like this:?
<:action :if={condition}>
...
</:action>
LostKobrakai
or better on the slot using :if as suggested by @matt-savvy. that way the slot is not passed with empty content to the component.
garrison
Tbh this is what convinced me that named slots are not a very good API. They’re a cool idea but they don’t hold up because they don’t compose properly. The introduction of :if and :for is, IMO, an ugly bandaid. Components are a more versatile primitive.
But yeah, as mentioned above, you have to use :if (or potentially :for) if you want to elide the slot itself from the output.
Alternatively you could ditch slots and use a component like <.article_action /> and then your intuitive solution would actually work.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









