ricksonoliveira

ricksonoliveira

Does anyone know how to use index when using Phoenix Live View stream/4 ?

for example when I do this:
<%= for {index, f} <- Enum.with_index(@streams.changeset) %>

I get:

[error] GenServer #PID<0.26435.0> terminating
** (ArgumentError) streams can only be consumed directly by a for comprehension.
If you are attempting to consume the stream ahead of time, such as with
`Enum.with_index(@stream.changeset)`, you need to place the relevant information
within the stream items instead.

I need to use the index inside my form for loop

First 10 of 12 Posts Switch mode

zachallaun

zachallaun

Can you expand on why you need to use the index?

The entire point of streams is to not keep the entire data set in memory, and you’d need that to have an index. If you can expand on what you’re doing with the index, perhaps someone here can suggest an alternative solution.

ricksonoliveira

ricksonoliveira OP

Thanks @zachallaun for the fast reply.
Sure I can expand. So, for example, right below the for loop with streams I’ll have something like:

<div id={"some-id-name-#{index}"} class="form-row form-row-indent-sm">

And so on, for example another use I’ll have to make with index is to show options on a select given the index
Like this:

<div class="flex-1">
  <%= select f, :type,
    get_options(index),
    disabled: @disabled
  %>
</div>

Is this enough? I know that usually people use IDs from changesets but in my case I wont have a changeset, at least not when the form renders for the first time, I’ll have to show empty inputs in this case.
Please tell me if you need more info.
Thanks so far!

codeanpeace

codeanpeace

Have you tried the suggestion in the error message?
How do you currently assign the stream and could you “decorate” the items with an index before streaming them?

ricksonoliveira

ricksonoliveira OP

Have you tried the suggestion in the error message?

I did after you mention but it was logic not to work since theres no :stream inside the assigns.

How do you currently assign the stream and could you “decorate” the items with an index before streaming them?

This is how I’m assigning:

def update(assigns, socket) do
    socket =
      socket
      |> assign(assigns)
      |> stream(:changeset, [to_form(User.changeset(%User{}, %{}))])
    {:ok, socket}
  end

As you can see I’m assigning an empty changeset to the stream in the update funciton for the first render, I’ll update the changeset in some event later on.
Actually I’d rather even just send an empty list to the stream, but then I wouldnt have a Phoenix.HTML.Form.

codeanpeace

codeanpeace

Hmm, is it really worth streaming a single form struct?

Streams were designed with collections in mind and the design pattern from form components created via the generators store the form struct as an assign which also makes it easy to update in the form validation callback like so:

  defp assign_form(socket, %Ecto.Changeset{} = changeset) do
    assign(socket, :form, to_form(changeset))
  end

  def update(%{list: list} = assigns, socket) do
    changeset = Todos.change_list(list)

    {:ok,
     socket
     |> assign(assigns)
     |> assign_form(changeset)}
  end

  def handle_event("validate", %{"list" => list_params}, socket) do
    changeset =
      socket.assigns.list
      |> Todos.change_list(list_params)
      |> Map.put(:action, :validate)

    {:noreply, assign_form(socket, changeset)}
  end
ricksonoliveira

ricksonoliveira OP

I understand, but see this case. I have a simple form with 2 inputs, a select and a text, this is a component, and below this form will be a button to add form that when clicked the same form will duplicate one above the other. So we can have multiple forms in there with no changesets, they can all be empty but I’ll have to use stream since these forms will be a list of forms. So this is why I need to use stream in here.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

I still think this is is sort of questionable. Are there going to be > 1000 forms? I can’t imagine how that would be good UX. If you have N forms I’d still just have N form components and probably make each of them a live component so that they can each manage their own events.

ricksonoliveira

ricksonoliveira OP

That’s plausible.
But then would you have just a simple for loop through the list of forms without using the stream?

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Yeah or depending on how your page is set up iterate through a list of users and then pass that user to a live component, and have each component generate their own form.

codeanpeace

codeanpeace

With the latest version of LiveView, you can use the new sort/drop_param and options for cast_assoc/embed in conjunction with inputs_for for Dynamically adding and removing inputs like so:

<label class="block cursor-pointer">
  <input type="checkbox" name="list[emails_sort][]" class="hidden" />
  add more
</label>

<input type="hidden" name="list[emails_drop][]" />

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
dli
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app? Looking for hints regarding: Addi...
New
roeland
Kia ora, We have been using elixir-google-api to connect to Google Drive. However, with the updates to Tesla due to CVEs this is now bro...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
rahultumpala
Hello, I have an Elixir backend that implements a custom protocol over TCP. I want to load test the backend and assess the performance o...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
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
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
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New

We're in Beta

About us Mission Statement