phlex icon indicating copy to clipboard operation
phlex copied to clipboard

Make __vanish__ part of the public API

Open joeldrapper opened this issue 1 year ago • 14 comments

Discussed in https://github.com/orgs/phlex-ruby/discussions/583

Originally posted by bradgessler July 21, 2023 Sometimes a component needs to be rendered, but the output is not needed, like in this controller at https://github.com/rubymonolith/classic/blob/47d9fee6e17f5f49d7dfbefee4b194b6eddcff8d/app/controllers/posts_controller.rb#L71-L73 so Superform can permit params based on the contents of a form.

Could this __vanish__ API be made available for such calls? I see I can include DeferredRender to enable that, but I only need this for permitting params. When I'm actually rendering the form in a view I don't need to defer rendering.

joeldrapper avatar Mar 27 '24 21:03 joeldrapper

@joeldrapper I'm willing to do this, I was wondering how do you imagine that would look? I was thinking about something like this:

  render ComponentToVanish.new(...).vanish

Vagab avatar Jun 19 '24 22:06 Vagab

I think it would mainly be used from inside the view_template method.

def view_template
  vanish do
    render SomeComponent.new
  end
end

Essentially all we need to do is rename the method removing the underscores.

joeldrapper avatar Jun 24 '24 19:06 joeldrapper

I think it would mainly be used from inside the view_template method.

might be misunderstanding the use case, but if it's used in the view_template, then what's the difference with just including DeferredRender? From @bradgessler's example it seems that it should be a regular template that just get's vanished when called from a specific context. Or am I missing something?

Vagab avatar Jun 25 '24 10:06 Vagab

Yeah, ideally I can vanish a component without having to throw it inside of another component.

If I were to implement Superform strictly to this spec, I'd have a VanishComponent that I'd pass the form component into, which would be kind of weird.

bradgessler avatar Jun 27 '24 03:06 bradgessler

@joeldrapper do you think it's worth doing something like what I suggested initially?

Vagab avatar Jul 01 '24 23:07 Vagab

@joeldrapper boop

Vagab avatar Jul 31 '24 21:07 Vagab

I think it would be reasonable for vanish to take either:

a renderable as the first positional argument, e.g.

vanish MyComponent.new

or a block, e.g.

vanish do
  h1 { "vanish this" }
end

joeldrapper avatar Aug 10 '24 15:08 joeldrapper

If the positional argument works from a controller, that would cover my use case of needing to vanish a form in Superform.

If it's only a block, I'd have to do some gymnastics with a throw-away n the controller to make it work.

bradgessler avatar Aug 10 '24 19:08 bradgessler

Neither would work form a controller. The only time Phlex supplements controllers is when you include Phlex::Rails::Streaming.

joeldrapper avatar Aug 12 '24 12:08 joeldrapper

@joeldrapper @bradgessler correct me if I'm wrong, but I don't think the suggestion of calling vanish from inside the component covers the initial use case this issue was created with. Should we consider having the ability to vanish from a controller? Maybe:

render Component.new(...).vanish
# or
render Component.vanish(...)
# or
include Phlex::Vanish
vanish Component.new(...)

otherwise if the direction you wanna go is vanishing from inside another component then I can just make __vanish__ public and rename it. Lmk wyt

Vagab avatar Aug 13 '24 16:08 Vagab

@joeldrapper I'm willing to do this, I was wondering how do you imagine that would look? I was thinking about something like this:

  render ComponentToVanish.new(...).vanish

I have a component forked off of Superform as well that needs this.

Current __vanish__ looks like it works as @joeldrapper describes here https://github.com/phlex-ruby/phlex/issues/698#issuecomment-2282193904.

However, the way you described it is how I actually need to use it.

I have a form which I wish to call vanish on. This can happen anywhere, so I don't want vanish form, I want form.vanish.


My actual implementation is a workaround that invokes #call

def extract_input(params)
  call unless @_rendered
  @namespace.extract_input(params)
end

thedumbtechguy avatar Aug 21 '24 09:08 thedumbtechguy

That checks out with how I use it in my implementations.

One thought: when the form is actually invalid, the output that was rendered should actually be displayed. Vanishing it means it would have to be rendered again without vanishing.

I think what I'd actually want is a way to render the view; if the form is valid I'd end up throwing that view away and redirecting the user to the success page. When the form is invalid, I'd actually want to render the output of Superform to the user since it would already have the UI rendered with error messages, etc.

bradgessler avatar Aug 21 '24 18:08 bradgessler

From what I’m hearing, it seems like you really need lower-level hooks into Phlex’ renderable interface so you can have custom form objects that are renderable in specific ways. I think ideally, those wouldn't inherit from Phlex::HTML and then use vanish to undo part of Phlex::HTML’s behaviour.

joeldrapper avatar Aug 22 '24 09:08 joeldrapper

@bradgessler then maybe actually just making vanish public would work? I'm not at all familiar with superform but could you do something like this from inside the form:

def view_template
  if valid?
    vanish
  else
    ...
  end
end

Vagab avatar Aug 22 '24 13:08 Vagab