Access to @socket in a Surface.Component

I am upgrading from Surface 0.5 to 0.6. It seems like @socket is not implicitly passed down to components anymore:

Request: GET /
** (exit) an exception was raised:
    ** (ArgumentError) assign @socket not available in template.

Please make sure all proper assigns have been set. If you are
calling a component, make sure you are passing all required
assigns as arguments.

Available assigns: [:__changed__, :__context__, :__surface__, :buttons, :default, :info, :inner_block, :messages]

I need @socket for all the route helpers, and it will be very inconvenient to pass down @socket as a prop for each component. Is there a better way?

Surface 0.6 only implicitly pass __context__ and __surface__, not socket anymore. My solution to this is to use the other form of the route helper: Routes.page_path(Endpoint, :index) in all surface templates, and I need to alias the Endpoint module, of course.

I kinda sense the rationale behind this change: The component now can be used in a dead view, where there is no socket. Nevertheless, this is a breaking change and it should better be documented in a upgrade guide sort of thing.

BTW: if you need to call the render/1 function directly for some reason, now you also need to explicitly pass __context__ and __surface__:

render(%{YOUR_ASSIGNS: YOUR_VALUES, __context__: @__context__, __surface__: @__surface__})
2 Likes