If you are thinking in trying Stimulus.js in your project, maybe this little “before and after” can help you to decide.
Today I was porting a small functionality to send some data to our analytics service from a “data-behavior” style of javascript sprinkles to Stimulus.js….
And I found very interesting that a lot of the code that we had to implement the feature was just to listen for the events and get the data from the html.
namespace = "project-item-track-click"
selectorFor = (name) -> "[data-behavior~='#{namespace}:#{name}']"
itemSelector = selectorFor("item")
containerSelector = selectorFor("container")
$items = ->
$(item) for item in $(itemSelector)
$linksForItem = ($item) ->
$(link) for link in $item.find("a")
getUserReferralCode = ->
$container = $(containerSelector)
$container.data("user-referral-code")
getRemainingDays = (targetDate) ->
diff = moment(targetDate).diff(moment(), "days") + 1
if diff > 0 then diff else 0
buildEventDataForItem = ($item) ->
data = {}
rawData = $item.data("for-event-tracking")
data[key] = value for key, value of rawData when key isnt "target_date"
data.remaining_days = getRemainingDays(rawData.target_date)
data.user_referral_code = getUserReferralCode()
data
initialize = ->
for $item in $items()
for $link in $linksForItem($item)
analytics.trackLink($link[0],
'Campaign Details Clicked',
buildEventDataForItem($item))
$(document).on "ready page:load", initialize
You can like the code or not, but look how although “our logic” was almost
just on the function buildEventDataForItem
and getRemainingDays
… It was
needed to write some funky and custom code to initialize the behavior and
get the needed data from the html.
import { Controller } from "stimulus"
import moment from "moment"
export default class extends Controller {
connect() {
let data = JSON.parse(this.data.get("eventData"));
this.setRemainingDaysOn(data);
this.setUserReferralCodeOn(data);
analytics.trackLink(this.element, "Campaign Details Clicked", data);
}
setUserReferralCodeOn(data) {
let code = document.body.dataset.userReferralCode;
data.user_referral_code = code;
}
setRemainingDaysOn(data) {
let targetDate = data.target_date;
delete data.target_date
data.remaining_days = this.remainingDays(targetDate)
}
remainingDays(targetDate) {
let diff = moment(targetDate).diff(moment(), "days") + 1
if (diff > 0) {
return diff
} else {
return 0
}
}
}
Again, you can like the code or not, but look how now almost all the code here is related to “our logic”… Now Stimulus.js is giving us an easy and standard way to initialize the behavior and fetch the data from the html.
I think is a nice improvement, don’t you think?
Here I try to share knowledge and fixes to common problems and struggles for ruby on rails developers, like How to fetch the latest-N-of-each record or How to test that an specific mail was sent or a Capybara cheatsheet. You can see more examples on Most recent posts or all posts.