Custom stimulus reflex class

668 views Asked by At

I am working on an experimental project in Rails 6. The purpose of this project for me is to learn new methodologies & play with new("ish") technologies.

In short, I am playing around with the Trailblazer infrastructure, stimulus_reflex & view_component accompanied by view_component_reflex.

From what I can tell, StimulusReflex & ViewComponentReflex expects reflex class to reside in a reflexes folder/namespace.

What I am trying to achieve:

Nest my ViewComponentReflex components in a Trailblazer concept folder (namespace).

What I have tried:

Created the following folder structure:

  • concepts/post/component/counter.rb
class Component::Counter < ApplicationComponent

  def initialize
    @loading = false
  end

  def loading=(new_value)
    @loading = new_value
    refresh! '#loader'
  end

  def do_expensive_action
    prevent_refresh!

    self.loading = true
    wait 20
    self.loading = false
  end

end
  • concepts/post/component/counter/counter.html.erb
<%= component_controller do %>
  <div id="loader">
    <% if @loading %>
      <p>Loading...</p>
    <% end %>
  </div>

  <button type="button" data-reflex="click->Component::Counter#do_expensive_action" >Load Content</button>
<% end %>

Expected Outcome:

I would expect the namespacing etc. to be allowed by Rails. When setting up the above & running a sample app, I am given the error: uninitialized constant Component::CounterReflex. The reliance of this class is built into one of the gems, but I am not sure where to find it. I have tried overriding some methods in ViewComponentReflex to no avail.

When I move my Component::Counter to the components folder (Like showed in this example), the code works.

Is there any way to redefine/-configure the route(module) of the reflex class using this stack?

UPDATE:

The GitHub repository for my app can be found here

The exact error message I see when hitting the counter button is:

StimulusReflex::Channel is streaming from StimulusReflex::Channel
06:48:27 log.1       | StimulusReflex::Channel#receive({"target"=>"Component::Counter#do_expensive_action", "args"=>[], "url"=>"http://krated.test/", "attrs"=>{"type"=>"button", "data-reflex"=>"click->Component::Counter#do_expensive_action", "data-key"=>"6b36d7d05b8737b0328d19bd2fff2679901b1736bb9e242b128e3b715aba6e87", "data-controller"=>"stimulus-reflex", "data-action"=>"click->stimulus-reflex#__perform", "checked"=>false, "selected"=>false, "tag_name"=>"BUTTON", "value"=>""}, "dataset"=>{"data-reflex"=>"click->Component::Counter#do_expensive_action", "data-key"=>"6b36d7d05b8737b0328d19bd2fff2679901b1736bb9e242b128e3b715aba6e87", "data-controller"=>"stimulus-reflex", "data-action"=>"click->stimulus-reflex#__perform"}, "selectors"=>[], "reflexId"=>"a091247b-d53b-4e63-ac59-78c72c4a3cb1", "permanent_attribute_name"=>"data-reflex-permanent", "params"=>{}})
06:48:27 log.1       | StimulusReflex::Channel Failed to invoke Component::Counter#do_expensive_action! http://krated.test/ uninitialized constant Component::CounterReflex /Users/hermann/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-6.0.3.3/lib/active_support/inflector/methods.rb:284:in `const_get
1

There are 1 answers

0
Roland Studer On

The version 2.3.5 of view_component_reflex expects components class names to end with Component. If they don't it fails. See https://github.com/joshleblanc/view_component_reflex/blob/v2.3.5/lib/view_component_reflex/engine.rb#L18

So try again with calling your component:

Component::CounterCountComponent