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

Showing Posts 1 to 10

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

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
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
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
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
ryanwinchester
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted” Version...
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
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
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

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews