DaAnalyst
The UC: I have two structures, each with its own lifecycle. The structure A is the larger one and is always fully rebuilt for each LV rendering cycle. The structure B is the configuration of the structure A, is small in size and is intended to be updated (not fully rebuilt) in each LV rendering cycle, with full reset on refresh. The structure B is a perfect candidate for the socket.assigns while the structure A is not for I don’t need it assigned.
However, both the rebuild of structure A instance and the updating of structure B instance take place within a single algo run. The problem that arises here is that I cannot call this algorithm from within the template as I don’t think (correct me if I am wrong) that there is a way to assign the updated structure B instance from the template. While if I run the algo from my LV module (in the handle_info function, for example) the only choice I have then is to assign both instances to socket.assigns for I don’t know how else I can make the structure A instance visible to the template.
In short, is there a point in the LiveView framework where I could compute the instances of both structures and assign just one of them, while making the other one also accessible to the template code, but without assigning it to the socket.assigns?
Trending in Discussions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
dom
How about keeping A in an assign, but marking it with
:temporary_assigns? Do you have a reason to keep it out of assigns besides memory usage?DaAnalyst
Temporary assigns are also assigns, it’s just that they get reset to a predetermined value by the framework. The reason why I’d like to, if possible, pass it to the template some way other than via assigns is that I don’t need it assigned and I don’t need the liveview to bother with it as the assigned changes that matter (that trigger the liveview to rerender) are assigned as well so there’s no need for this structure to trigger it as well. Actually, the thing is that I don’t know what the expense of having structures assigned to LV socket with respect to the LV behavior is. The documentation is very opaque on the inner workings of the LV and I simply don’t have time to reverse engineer the code.
benwilson512
Are you constructing it in the
def rendercallback?Do note that if live view can determine that the assigns have not changed it will not re-render that part of the page, nor will it push updates over the wire.
Some of this feels like premature optimization.
Assigns are the only way to get a value in the template, you do need it to be assigned. I would start with the simple assign based solution, and then measure memory usage and benchmark various aspects of your live view. If you have memory savings you want to achieve, temporary assigns are the solution. If it isn’t clear how to apply those to your situation, that’s the line of questioning that is likely to be most productive.
DaAnalyst
No. I do it in handle_info where I handle data model change messages (that I subscribe my LV module to). But it’s pretty much the same thing,
Correct me if I am wrong, but AFAIK the LiveView simply requires whatever to change in its assigns to rerender. And when re-rendering it’s sending the diffs resulting from your template code.
Thank you for pointing this out. Just needed this confirmation so I don’t waste time speculating. As I said, my structure A instance gets fully reconstructed based on other data (structure B and some other data) that get assigned anyway, so technically, another assign of structure A (which is a data transformation of the aforementioned) is redundant. The only reason why I end up needing it assigned is the point that you emphasized (being the only method to pass it to the template). Just wanted to make that clear. Thanks.
DaAnalyst
Btw, this is the second time so far I happen to need something like :ignored_assigns.
benwilson512
Live view has several optimizations to do better than this. For example if you render a partial, and none of the assigns passed to the partial have changed, the entire partial will not be re-rerendered. This may be true for things like
ifblocks too, I don’t remember off the top of my head.Ah so, this might seem to be the same, but it is importantly very different. Render is called after every
handle_function returns, every time. If the only thing that ever happens is a specifichandle_infoclause then I guess they’ll run with basically the same frequency, but I do think the distinction matters.Can you elaborate how this would work?
DaAnalyst
Look. For all I know, it takes a single non-related assign to get it to rerender everything that changed. For instance, if you have an input text change that you handle the blur event for and your business logic rejects the change for some reason, you can’t just change this specific state in your liveview structure for it remained as it was prior to the change and LV would not revert the content of the input text element to what it was before. That is unless, of course, you assign, say an unrelated temporary assign which will make it take into account the diffs between the dom tree and the liveview state and, effectively, revert the undesired change in the input field.
Of course.
It would simply denote the particular assign as an argument available to the template, that is should any rerendering be triggered otherwise, but should not consider the particular assign to trigger the rerendering.
benwilson512
To some extent this is just fundamentally at odds with the live view paradigm. What you’re suggesting is basically a side cause, a value that is not treated as an input to the render function, but rather a thing that simply happens to be available. This is fundamentally at odds with how LiveView (and similar UI frameworks) treat rendering, it is a pure relation between a set of inputs and an outputed template. This is, for example, why calling
DateTime.utc_now()in your template or in a view helper will not work correctly, and why you should instead do|> assign(:now, DateTime.utc_now())and use@now.However! Perhaps the issue here is that you’re operating as if the socket assigns are the only way to maintain state on the socket. Maybe using the
privatekey of the socket will help, so that you can hold on to a value and then only at some later time actually add it to the assigns to be rendered. You could place the value you get from handle_info in the socket private key, and then you can have some other event move the value from private to assigns when you want it to effect the view.DaAnalyst
Maybe, but you must admit that even you called for it implicitly several comments above:
I don’t do things like this for I don’t keep any logic whatsoever in my templates, but I’d like to know why you are suggesting it be wrong execution-flow -wise if at all. Or it’s about error/exception handling, suggesting the template should only read pre-computed data from structures (which too can be subject to runtime exceptions, so I don’t see the point if this is the argument).
Not my case. I don’t need it for later use, I just don’t know the expense for LV to handle each assign and by default, I tend to minimize the unnecessary operations, although this expense may be insignificant. As originally stated, calling the computation function directly from template would be ideal (unless there is something I am not aware of), for this is a completely redundant state to the one already assigned to the LV socket.
Btw, how do I access this private key if I want anything stored there? Manually - by modifying the structure directly? I am not aware of LV functions for that.
Also, if I store anything in this private key, is it like an assign or like a temporary assign in terms of the lifecycle?
benwilson512
It is like an assign, in that once placed is is there in memory, although it is not available in the template, nor will changing it trigger a re-render. Think ordinary genserver state.
Yes, it is a documented part of the structure, you can safely access it directly.
If I was unhappy about assigns being the only way to get data in, then sure, but I’m very happy that assigns are the only way to get data in. This provides all sorts of wonderful guarantees that make reasoning about views easier, and provides great hooks for automatic optimizations that obviate the need to try to create complicated ones like you are doing.
It’s wrong because the moment you have side causes rendering isn’t pure. If rendering isn’t pure, it makes the question “when to render” a vastly more complex one that you suddenly have to manage. LiveView’s paradigm, much like react and other similar paradigms is: Update the state => render. If the state updates, the output from render will reflect that state. This is an amazing guarantee, and it makes reasoning about live view incredibly easy. If you introduce side causes, changing state is no longer enough to know that you need to trigger a re-render. Your ability to reason in a linear path about the state of the live view process and the content of the template goes out the window.
Pure render functions improve performance as well. You seemed to simply not believe me before, but LiveView really does have the assign diffing optimizations, and with pure rendering it can also safely increase those optimizations as time goes on. I know for sure it works with live components and render calls, if you didn’t see it in your use case I’m happy to dig into the specifics with actual code. If render functions aren’t pure though, the ability to get automatic optimizations via assign diff tracking also goes out the window, because we no longer know that we can derive a template from the assigns.