How to handle form errors

Hi guys,

I am a django developer, and I am trying have you try to implement a form in stimulus? I’m a bit confused with something, let me explain.

I felt that stimulus encourages us to use html over json. So for example, in a todo app, if I have a form to create a new task - when I submit with a valid input, I return from the server the html with that task and insert that html in the task list.

That one feels great, but what about when the form gets an error? Here I’m says errors from the server, like the task has already another with the same name for example. You return an html with the errors too?

When you choose to use stimulus over turbo links? What your thoughts about that?

Best Hélio

When you choose to use stimulus over turbo links? What your thoughts about that?

You can use stimulus and turbolinks together. They are designed to work well with each other.

Here I’m says errors from the server, like the task has already another with the same name for example. You return an html with the errors too?

That is one option, yes. If you are using turbolinks you can just make a POST and get a new page back, leaving turbolinks to handle the page refresh so it feels fast.

In my project I use also rails-ujs and often use so called Server-generated JS responses (SJR).

In case of error I trigger CustomEvent on document with error in detail. Server returns following JS and browser evaluate it:

var event = new CustomEvent('action:error', {
  detail: {
    message: "<%= j errors_text.html_safe %>"
  }
});

document.dispatchEvent(event)

And I have controller that handle it. Source code: https://github.com/skyderby/skyderby/blob/dev/app/javascript/controllers/action_errors_controller.js

Here is how it looks like:

Yeah I know that we can use together, its more about in which actions do you use turbo links and which parts you use stimulus.

Okay, Thanks for share. I’ve made a version more less with that idea if I understand it wright.

With that approach I have to create an extra target, because if I print the error from the server (for example the field is required) when i submit again with a value the error message don’t disappear.
With that extra target it works, but maybe here, with turbo links make it nicer.

With the following code if it passes clears the error message if exists and append the new task on the current one. If it fails it renders the partial template with the input and the error.

axios.post(form.getAttribute('action'), {name: this.nameTarget.value})
      .then((response) => {
        Turbolinks.visit('/', { action: 'replace' });
      }).catch(error => {
        form.innerHTML = error.response.data.template
      });

Maybe this one type of project a todo list has a bit more logic to just use stimulus, with the addition of turbo links simplify the code. For sites more simples when you just need some simple “sprinkles” using stimulus standalone it enough.

I wrote a piece about dealing with form errors with modern Rails. It features a stimulus controller leveraging HTML5 form validations for the client-side and some tips on how to handle server-side validations in a consistent manner.

4 Likes