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! 🛀
Want to read me more?
-
String Inflectors: bring a bit of Rails into JavaScript
This article, extracted from the book JavaScript for Rails Developers, explores creating handy helpers, like `camelize` and `ordinalize`, inspired by Rails. -
Conditionally Add CSS Classes in Your Stimulus Controllers
You can cleanup your Stimulus controllers by using a simple vanilla JavaScript function. -
Multiple component variants with Tailwind
Building components with multiple variants is easy with Tailwind CSS. If you know how to do it.
Over to you…
What did you like about this article? Learned something knew? Found something is missing or even broken? 🫣 Let me (and others) know!
Comments are powered by Chirp Form
{{comment}}