Is there any way to consume a stream with a hook?

I have a hook wrapping a JS component. I’m currently passing a single JSON value into it that’s generated by my LiveView. Because setting a single data-events={@events} doesn’t use a for comprehension, I have to assign that data, rather than streaming it.

Is there any way to use a stream with a hook? The only thing I can think of is converting the hook to a webcomponent with slots:

<calendar>
  <event :for={{id, event} <- @stream.events} id={id} slot="events" data={Jason.encode!(event)} />
</calendar>

Thanks!

I don’t think streams work like that. They put the state in the liveview frontend but you want it in the hook if you’re controlling the DOM. It depends on if/where you give control of the DOM to the hook.

You don’t have to assign it to get it to the hook. You could chunk it or send what is needed to the hook using push_event. You can message back and forth this way.

1 Like

Yeah, sadly that’s the tricky part. I’d love for LiveView to manage the state, and my hook to just react to the items that are added/changed/removed. I’m brute-forcing this now with a JS Observer watching its data-events prop.

I hadn’t thought of using push_event. That’s better than my current workaround as the data’s not sitting in memory like the assigns. Thanks! I think this is probably the best option we have for now.

1 Like

I agree it would be nice if live view could track front end state as well. It could provide component attrs (perhaps just a state macro) %JS{} events for interfacing with it. It’s already tracking dynamic data so the function for setting state already exists somewhere, it just needs a public version that limits the type of data it can accept. This is where the proposed component state macro come in, it would tell live view ahead of time the type of data to track. It doesn’t need to support all types of data, live view is meant to be a server first framework after all, but if LiveView could track basic JS primitives like numbers, booleans, and strings that’d already be pretty helpful.

1 Like