Class: Phlex::Reactive::Response
- Inherits:
-
Object
- Object
- Phlex::Reactive::Response
- Defined in:
- lib/phlex/reactive/response.rb
Overview
An explicit, immutable description of the ACTOR’s HTTP response to a reactive action. An action MAY return one; if it returns anything else (the legacy contract — return value ignored), the endpoint falls back to the implicit single component.to_stream_replace.
A Response governs ONLY the actor’s HTTP reply. Cross-tab updates still go through Streamable’s broadcast_*_to(…, exclude: reactive_connection_id).
Response.replace(self) # re-render in place (the default, explicit)
Response.replace(self).flash(:error, msg) # surface a validation error
Response.remove(self) # drop the element (e.g. moderation queue)
Response.redirect(article_url(@article)) # slug changed -> Turbo.visit the new URL
Response.replace(self).stream(Totals.update(@order)) # multi-stream
Instance Attribute Summary collapse
-
#redirect_url ⇒ Object
readonly
Returns the value of attribute redirect_url.
-
#streams ⇒ Object
readonly
Returns the value of attribute streams.
Class Method Summary collapse
-
.flash_stream(_level, content, target:) ⇒ Object
Build a flash turbo-stream that appends ‘content` into a host-app container.
-
.redirect(url) ⇒ Object
Client-side full navigation (Turbo.visit).
-
.remove(component) ⇒ Object
Remove the component’s element from the DOM.
-
.replace(component) ⇒ Object
Re-render the component in place (explicit form of today’s default).
-
.update(component) ⇒ Object
Morph only inner HTML (preserves the root element + its token attr).
-
.with(*strings) ⇒ Object
Escape hatch / multi-stream root: zero or more raw turbo-stream strings.
Instance Method Summary collapse
-
#flash(level, content, target: Phlex::Reactive.flash_target) ⇒ Object
Append a flash turbo-stream into a host-app container (default <div id=“flash”>, configurable via Phlex::Reactive.flash_target).
-
#initialize(streams: [], redirect_url: nil, render_self: true) ⇒ Response
constructor
render_self: when true (default for replace/update/with), the endpoint GUARANTEES the component’s own replace is present so its data-reactive-token-value refreshes (the client extracts the next token from the response HTML).
- #redirect? ⇒ Boolean
- #render_self? ⇒ Boolean
-
#stream(*more) ⇒ Object
Append extra turbo-stream strings (a sibling component, a flash).
Constructor Details
#initialize(streams: [], redirect_url: nil, render_self: true) ⇒ Response
render_self: when true (default for replace/update/with), the endpoint GUARANTEES the component’s own replace is present so its data-reactive-token-value refreshes (the client extracts the next token from the response HTML). remove/redirect set it false (nothing stays).
56 57 58 59 60 61 |
# File 'lib/phlex/reactive/response.rb', line 56 def initialize(streams: [], redirect_url: nil, render_self: true) @streams = streams.freeze @redirect_url = redirect_url @render_self = render_self freeze end |
Instance Attribute Details
#redirect_url ⇒ Object (readonly)
Returns the value of attribute redirect_url.
19 20 21 |
# File 'lib/phlex/reactive/response.rb', line 19 def redirect_url @redirect_url end |
#streams ⇒ Object (readonly)
Returns the value of attribute streams.
19 20 21 |
# File 'lib/phlex/reactive/response.rb', line 19 def streams @streams end |
Class Method Details
.flash_stream(_level, content, target:) ⇒ Object
Build a flash turbo-stream that appends ‘content` into a host-app container. `content` is a Phlex component instance (rendered through the configured renderer so t()/url_for work) or a ready HTML string —supplied by the caller because the render context is off-request (there is no Rails `flash`).
46 47 48 49 |
# File 'lib/phlex/reactive/response.rb', line 46 def flash_stream(_level, content, target:) html = content.is_a?(::Phlex::SGML) ? Phlex::Reactive.render(content) : content.to_s Phlex::Reactive.flash_builder.append(target, html: html) end |
.redirect(url) ⇒ Object
Client-side full navigation (Turbo.visit). Use when the current URL is dead (slug rename) or the outcome belongs on another page. Pass a *_url (the off-request render context has no request host for *_path).
36 |
# File 'lib/phlex/reactive/response.rb', line 36 def redirect(url) = new(redirect_url: url, render_self: false) |
.remove(component) ⇒ Object
Remove the component’s element from the DOM. Uses the instance to_stream_remove (the component already knows its own #id — no class-builder reconstruction; works for record- and state-backed).
31 |
# File 'lib/phlex/reactive/response.rb', line 31 def remove(component) = new(streams: [component.to_stream_remove], render_self: false) |
.replace(component) ⇒ Object
Re-render the component in place (explicit form of today’s default).
23 |
# File 'lib/phlex/reactive/response.rb', line 23 def replace(component) = new(streams: [component.to_stream_replace]) |
.update(component) ⇒ Object
Morph only inner HTML (preserves the root element + its token attr).
26 |
# File 'lib/phlex/reactive/response.rb', line 26 def update(component) = new(streams: [component.to_stream_update]) |
.with(*strings) ⇒ Object
Escape hatch / multi-stream root: zero or more raw turbo-stream strings.
39 |
# File 'lib/phlex/reactive/response.rb', line 39 def with(*strings) = new(streams: strings.flatten) |
Instance Method Details
#flash(level, content, target: Phlex::Reactive.flash_target) ⇒ Object
Append a flash turbo-stream into a host-app container (default <div id=“flash”>, configurable via Phlex::Reactive.flash_target).
75 76 77 |
# File 'lib/phlex/reactive/response.rb', line 75 def flash(level, content, target: Phlex::Reactive.flash_target) stream(self.class.flash_stream(level, content, target:)) end |
#redirect? ⇒ Boolean
79 |
# File 'lib/phlex/reactive/response.rb', line 79 def redirect? = !@redirect_url.nil? |
#render_self? ⇒ Boolean
80 |
# File 'lib/phlex/reactive/response.rb', line 80 def render_self? = @render_self |
#stream(*more) ⇒ Object
Append extra turbo-stream strings (a sibling component, a flash). Returns a NEW Response (immutable).
65 66 67 68 69 70 71 |
# File 'lib/phlex/reactive/response.rb', line 65 def stream(*more) self.class.new( streams: @streams + more.flatten, redirect_url: @redirect_url, render_self: @render_self ) end |