Rails flash notifications with Stimulus


Rails flash is an effective way to inform users after an event, for example: login successfully, invalid data/actions.

Normally we display flash as part of Rails layout but this has gone out of style as the pop up notification style becomes popular with the heavy use of JS on frontend. The popup notification style also has advantage of not taking space of the template itself.

In this article I will demonstrate how to display Rails flash messages as popup notification with Stimulus and Noty. You could replace Noty with other popup/modal js packages easily.


View partial

<% flash.each do |type, message| %>
  <div data-controller="notification">
    <input data-notification-target="type" value="<%= type %>" type="hidden">
    <input data-notification-target="message" value="<%= message %>" type="hidden">
  </div>
<% end %>

Stimulus controller, in this case notification_controller

import { Controller } from 'stimulus'
import Noty from 'noty'
import 'noty/src/noty.scss'
import 'noty/src/themes/mint.scss'

export default class extends Controller {
  static targets = [ 'type', 'message' ]

  connect () {
    new Noty({
      text: this.messageTarget.value,
      type: this.getNotificationType(),
      theme: 'mint',
      progressBar: true,
      timeout: 5000,
    }).show()
  }

  getNotificationType () {
    switch (this.typeTarget.value) {
      case 'notice':
        return 'info'
      case 'success':
        return 'success'
      case 'error':
        return 'error'
      case 'alert':
        return 'warning'
      default:
        return 'info'
    }
  }
}

How the code above works:

  • We render flash type and message in hidden inputs so it won't display on the page.
  • We take advantage of Stimulus connect(). This triggers when an element attached to notification controller appears.
  • In connect() method we run the code to show the popup notification. getNotificationType() method is used to map Rails flash types with Noty notification types. It would be varied based on the notification lib.

That's all Folks!