Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrading from v1.2.2 to v1.3.1 resets the input value #55

Closed
damir opened this issue Jan 28, 2024 · 10 comments
Closed

Upgrading from v1.2.2 to v1.3.1 resets the input value #55

damir opened this issue Jan 28, 2024 · 10 comments

Comments

@damir
Copy link

damir commented Jan 28, 2024

Hi Max,

I added 200 ms delay in handle_params so it is visible in the recording below.

The log is the same in both versions:

[debug] HANDLE EVENT "option_click" in LiveUIWeb.Admin.UserLive.Index
  Component: LiveSelect.Component
  Parameters: %{"idx" => "0"}
[debug] Replied in 118µs

[debug] HANDLE EVENT "users-update-filter" in LiveUIWeb.Admin.UserLive.Index
  Parameters: %{"_target" => ["company_id"], "company_id" => "1", "company_id_text_input" => "ACME INC", "filters" => %{"0" => %{"field" => "company_id"}, "1" => %{"field" => "email", "op" => "ilike", "value" => ""}}}
[debug] Replied in 173µs

[debug] HANDLE PARAMS in LiveUIWeb.Admin.UserLive.Index
  Parameters: %{"_target" => ["company_id"], "company_id" => "1", "company_id_text_input" => "ACME INC", "filters" => %{"0" => %{"field" => "company_id"}, "1" => %{"field" => "email", "op" => "ilike", "value" => ""}}}
[debug] QUERY OK source="users" db=0.3ms idle=1814.9ms
SELECT ...
[debug] QUERY OK source="users" db=0.2ms idle=1816.1ms
↳ Flop.meta/3, at: lib/flop.ex:929
[debug] Replied in 2ms

It is triggered when the updated stream is added to the socket:

socket |> stream(:items, items, reset: true)

Looks like the whole component is re-rendered:

Screenshot 2024-01-28 at 11 32 33 AM
live_select.mov
@maxmarcon
Copy link
Owner

Hi Damir. Can you please share a minimal example (ideally with a repo) that reproduces the issue? Thanks

@shamanime
Copy link
Contributor

I am facing the exact same issue, I have two components on the page and the component is reset suddenly after a few ms. Debugging it right now. Let's see if I can help.

@maxmarcon
Copy link
Owner

@shamanime thanks, that would be really helpful. If you could create a minimal repo that reproduces the issue, that should be enough for me to dig into it and fix it.

@shamanime
Copy link
Contributor

I've updated this repo to simulate the issue: https://github.com/shamanime/async_stream_test

Run it, add a user, go to the show page, click edit, update cars/fruits and click save. This action won't redirect/patch, instead it will just reload the form and then the live_select options disappear.

I've sent you a DM on Elixir's Slack. Ping me there if you need more details or want to pair on it.

@maxmarcon
Copy link
Owner

thanks a ton @shamanime ! I can replicate the issue using your repo. I will dig into it soon.

@maxmarcon
Copy link
Owner

Thanks again for putting together the repo.

The problem here is that live select doesn't know how to map the shape of the AsyncStreamTest.Accounts.Item into an option.

You're working around this problem in your update/2 callback in the FormComponent, however, the callback is no longer being called when the form is simply reloaded, and so the selected options disappear. In any case, having to write this logic in the update/2 callback is cumbersome and counterintuitive.

Live select looks at the value of the form's field, and assumes it's in the expected format for an option. I realize now that this is a bit naive and only works for simple fields like integers and strings, but not for fields whose values can be structs, like in your case.

Perhaps a possible solution could be to provide a value_mapper assign. The user could use the assign to pass a function that maps the value in the form to the value expected by live select.

For example, in your case, something like this:

<.live_select value_mapper={fn %Item{name: name, id: id} -> %{label: name, value: id} end} />

What do you think?

@maxmarcon
Copy link
Owner

it seems to be more complex than I initially thought. The element of an embedding could also be a changeset .

I need to think about it with more calm. Any idea is welcome!

@maxmarcon
Copy link
Owner

FYI: Ok I think I wrapped my head around this. Will come back with a plan when I find some time. Stay tuned!

@maxmarcon
Copy link
Owner

maxmarcon commented Mar 11, 2024

@shamanime I made LiveSelect changeset aware, so it can now handle embedded schemas easily. I also added a value_mapper assign with which you can pass a function to map your embedded schema to LiveSelect options.

These changes aren't in main yet, but in a separate value_mapper branch.

I created a PR for your application that explains and showcases the changes:

shamanime/async_stream_test#1

Everything should be much simpler now and work without problems. There are still some open questions though, I'd be very thankful for your feedback! 🙏

@maxmarcon
Copy link
Owner

Closed with 1.4.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants