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

Allow forcing $id to always generate a fresh id #4106

Closed
wants to merge 3 commits into from

Conversation

willrowe
Copy link
Contributor

A couple of months ago I made this demo after I got an idea of a way to use $id to make a quick and easy form with a dynamic number of fieldsets using the same template.

I used v3.13.3 at the time and it worked great! However, recently I needed this functionality on a real world project, so I pulled up the demo and copied over the concept, it didn't work. After some debugging I found that the $id call on the button click was no longer creating new ids each time it was clicked.

At first I thought this was a bug due to this recent update in Alpine, but then I realized that I was actually relying on a bug in v3.13.3 that just happened to make the demo to work as I wanted. Conceptually, it makes perfect sense that a call to $id on the same element would always return the same value, that's exactly what it's for.

After realizing my mistake, I added the 'Altered Version' to the demo with a secondary variable in the x-data that tracks how many times the button has been clicked. While this works just fine, I was left feeling like it was a shame there wasn't a more simple way to just use $id to generate a fresh value each time and not have to rely on an extra counter variable with no other purpose. I tried a couple of different variations and landed on adding a third argument to $id to allow caching to simply be disabled for a specific call. $id will still function exactly the same unless false is explicitly passed as the third argument, denoting that a new value should be returned each time it is run.

@calebporzio
Copy link
Collaborator

Hey @willrowe - I hesitate to make the $id more complicated with flags and such.

Is there a simple snippet you could use to avoid $id alltogether?

Like something manual like this?

<div x-data="{ id: (Math.random() + 1).toString(36).substring(7) }"x-bind:id="id">

Let me know if I'm missing something and there is no good way to accomplish this in userland, otherwise I'll probably close this. Thank you for your willingness to contribute though!

@willrowe
Copy link
Contributor Author

@calebporzio thanks for taking a look. As I mentioned, I did come up with a way to do this by using a counter variable, it just didn't feel like a very clean solution since the variable isn't used for anything else and requires manually incrementing.

The main goal is to generate a value that is unique on the page, so your snippet would not actually work since Math.random() can very easily collide. In my demo the unique value is specifically needed to be used for a x-for key so the items would be stable, but I can imagine there are other use cases as well.

After thinking about it a bit more though, it would probably be better to not have this as part of $id, since it already has well defined functionality around grouping. I'll probably come up with a separate magic that always generates a unique identifier that I can include in my own projects.

@willrowe willrowe closed this Mar 27, 2024
@willrowe willrowe deleted the feature/force-fresh-ids branch March 27, 2024 17:43
@ekwoka
Copy link
Contributor

ekwoka commented Mar 28, 2024

If it's a form of some kind, wouldn't the form itself already have unique identifiers to handle this?

@willrowe
Copy link
Contributor Author

@ekwoka do you have a simple example of what you mean?

@ekwoka
Copy link
Contributor

ekwoka commented Mar 28, 2024

I just mean, if you're submitting the data from forms.

How would the form know what each would be? Or are you trying to use Alpine to differentiate them?

@willrowe
Copy link
Contributor Author

willrowe commented Mar 28, 2024

The demo I linked to shows exactly what I was trying to do. Existing data is preloaded into the form, but I'm using Alpine to allow new items to be generated.

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

Successfully merging this pull request may close these issues.

3 participants