A lot of times when I write functional components and live components, I want to make sure I don’t end up with duplicate HTML IDs so I do something like
I think the last one is best because it is “random” instead of “unique”. Since I am only trying to safeguard against duplicate HTML IDs in the same page, using a “unique” generating function feels excessive.
The question: how do you avoid duplicate HTML IDs and what is a well-suited function to use for doing it?
Why would it be excessive? All that System.unique_integer/0,1 promises is that it will not return the same value twice for the same options, so it’s actually a very cheap function, it essentially just bumps a thread-local counter and returns it.
The requirement comes from LV. It tracks dom node livecycles via ids (so that a new id means a new livecycle) e.g. for hooks as well as for streams. Sometimes being unique is enough of a property to make those things work, even if there’s no further targeting of those ids. It’s enough that they happen to be different.
This is one of these things where I feel friction with liveview sometimes. I don’t really want to give some things an id, but I have to for liveview. So I’d rather hide it.
To be fair, sometimes you do want an id and then I want to make it visible/explicit.
Mostly in the ability to change how you generate IDs later, plus also being able to parse them and infer anything internal encoded inside of them (like a DB ID).
Granted not the most solid of arguments but I had such needs in the past (not with LV) so I came to appreciate having escape hatches.
I swear either Phoenix or Liveview has an internal function for making random uniqueish binary refs in its internals that I’ve stolen for similar purposes before, but I’m having trouble finding it.
defp random_ref() do
binary = <<
System.system_time(:nanosecond)::64,
:erlang.phash2({node(), self()})::16,
:erlang.unique_integer()::16
>>
Base.url_encode64(binary)
end
I borrowed it because I was messing with a custom Tracker-compatible system and wanted same-format ids, but also reasoned if it was good enough for Phoenix it was probably fast enough for my other usecases in the application as well, so I used it for some DOM id generation as well.