Available Now JavaScript for Rails Developers

Sanitize your strings in JavaScript like a Rails developer

This article is extracted from the book JavaScript for Rails Developers. Get your copy today. ✌️


Ruby (and Rails) are known for great Developer Experience. Not in the least because of the many little helpers available. JavaScript doesn’t have most of these unfortunately, but luckily, as a developer, many are easily replicated. Let’s look at the API I am looking for:

class Editor {
  async #update(content) {
    const sanitizedContent = sanitize(content, { trimTrailingWhitespace: true })

    const response = await fetch(
      this.updateUrlValue,
      {
        // …

        body: JSON.stringify({
          content: sanitizedContent
        })
      }
    )

    // …
  }
}

sanitize(content, { trimTrailingWhitespace: true }) is what I want to implement. You could extend the options with whatever you need:

sanitize(content, {
  trimTrailingWhitespace: true,
  trimLeadingWhitespace: true,
  maxConsecutiveNewlines: 2,
  maxConsecutiveSpaces: 1
  // … etc.
})

The code for it is quite simple really! Let’s create it at: app/javascript/helpers/textSanitizers.js.

// app/javascript/helpers/textSanitizers.js
class TextSanitizers {
}

export const sanitize = (content, options = {}) => {
  return new TextSanitizers(content).process(options)
}

Above shows that the content is passed as an argument and then very likely set as an instance variable. It also needs a process method.

class TextSanitizers {
+  constructor(content) {
+    this.content = content
+  }

+  process(options = {})
+    return this.content.replace(/[ \t]+$/gm, "")
+  }
}

Above is all that is needed to sanitize trailing white-spaces from the content. But I want this class to be responsible for many more sanitizations! Let’s set it up to be ready for that.

class TextSanitizers {
+  availableCleaners = [
+    "trimTrailingWhitespace"
+  ]

  constructor(content) {
    this.content = content
  }

  process(options = {}) {
-   return this.content.replace(/[ \t]+$/gm, "")
+   return Object.entries(options).reduce((result, [option, value]) => {
+     return this.availableCleaners.includes(option) ? this[option](result, value) : result
+   }, this.content)
  }

  // private

+  trimTrailingWhitespace(text) {
+    return text.replace(/[ \t]+$/gm, "")
+  }
}

The process method determines which cleaning operations need to run. When no options are passed, it defaults to an empty object ({}). Then inside the method Object.entries converts the options into an array of key-value pairs: {trimTrailingWhitespace: true} would become: [["trimTrailingWhitespace", true]]. If this seems like a lot, the book JavaScript for Rails Developers has you covered (more sanitization options included)! 😊

Okay, with that done, it is now easy to extend TextSanitizers class with more options:

class TextSanitizers {
  availableCleaners = [
    "trimTrailingWhitespace",
+   "trimLeadingWhitespace",
+   "maxConsecutiveNewlines",
+   "maxConsecutiveSpaces"
  ]

  constructor(content) {
    this.content = content
  }

  process(options = {}) {
    return Object.entries(options).reduce((result, [option, value]) => {
      return this.availableCleaners.includes(option) ? this[option](result, value) : result
    }, this.content)
  }

  // private

  trimTrailingWhitespace(text) {
    return text.replace(/[ \t]+$/gm, "")
  }

+ trimLeadingWhitespace(text) {
+   return text.replace(/^[ \t]+/gm, "")
+ }

+ maxConsecutiveNewlines(text, maxNewlines) {
+   return text.replace(/\n{3,}/g, "\n".repeat(maxNewlines))
+ }

+ maxConsecutiveSpaces(text, maxSpaces) {
+   return text.replace(/ {2,}/g, " ".repeat(maxSpaces))
+ }
}

For every new sanitization option, you add it to availableCleaners and then add the method with a matching name.

And that is how you added a little bit of Rails into JavaScript. Super clean! 🛀

Published at . Have suggestions or improvements on this content? Do reach out.

Join Rails developers getting deep dives on modern front-end patterns—from Hotwire, Tailwind CSS and ViewComponent. Fresh insights from Rails Designer HQ.
JavaScript for Rails Developers
Out now

UI components Library for Ruby on Rails apps

$ 149 one-time
payment

View components
  • One-time payment

  • Access to the entire library

  • Built using ViewComponent

  • Designed with Tailwind CSS

  • Enhanced with Hotwire