Stimulus and flash error messages

Hello,

I was migrating most of our apps code to stimulus controllers and got stuck. The problem in question is that we have a form thats being submited via .ajax and if the underlying model is not valid we get a flash message displaying the error. However, after I transfered the code to a stimulus controller using the .ajax everything goes well: we submit the form successfully if the model is valid and get the same responses from the server, BUT there is no flash message shown if the model is not valid. The request header is the same and the message is inside it using both methods, but when we use stimulus its just not showing up on the page. Please share your experiences and ask questions. I will be happy to post code if you need further info.

Assuming that you are using server-side javascript and remote elements (remote: true), I have been using the following pattern.

Rails controller

def update
  @model = Model.find(params[:id]
  if @model.update_attributes(model_params)
    render @model, layout: false
  else
     render 'error', errors: @model.errors.full_messages, layout: false
  end
end

View

<%= form_for @model,
             remote: true,
             data: {
               action: 'ajax:error->onSaveFail',
               controller: 'form'
             } do |f| %>
  <div data-target="form.errors">
  </div>
  <!-- other form fields -->
<% end %>

Error Partial

<% if local_assigns.has_key? :errors %>
  <% if errors.any? %>
    <div class="bg-red-lightest border-l-4 border-red text-red-dark p-4 mb-4 text-left">
      <% errors.each do |msg| %>
        <p class="mb-0"><%= msg %></p>
      <% end %>
    </div>
  <% end %>
<% end %>

form_controller.js

export default class extends Controller {
  static targets = [
    'errors',
  ];

  onSaveFail(event) {
    const [data, status, xhr] = event.detail;
    this.errorsTarget.innerHTML(xhr.response);
  }
}
2 Likes