How to Pass Data From Rails to Javascript / Coffeescript
Written by Chris • 7 May 2017
If you want to pass data between Rails and Coffeescript in your apps, you'll
find that interpolation doesn't work. For example:
# app/assets/javascript/home.coffee
$ ->
$('#some_element' ).text('<%= @user.id %>')
If you look at the resulting Javascript, you'll see that the string is
interpreted literally, rather than interpolating the user's id
:
;(function () {
$(function () {
$("#some_element").text("<%= @user.id %>")
})
}.call(this))
Quickfix
You can quickly fix this by appending .erb
to the Coffeescript's filename.
This will instruct the asset compiler to parse the file through ERB before
Coffeescript, resulting in the value being correctly interpolated:
# app/assets/javascript/home.coffee.erb
$ ->
$('#some_element' ).text('<%= @user.id %>')
// (resulting Javascript)
;(function () {
$(function () {
$("#some_element").text("32")
})
}.call(this))
A More Flexible Approach
However, I feel this too tightly-couples the Javascript and Rails code. I much prefer to follow Rails' own
unobtrusive-Javascript approach, and make use of HTML5 data attributes to
pass data between the front-end (JS) and back-end (Rails) code. Using the example above, the id
would be passed
as an arbitrary data attribute on the HTML element:
# app/views/home/index.html.erb
<div class="user-details" data-user-id="<%= @user.id %>">
</div>
Now in the Javascript, you can easily extract the value of data-user-id
. Furthermore, you can use the same code
to act on any HTML element containing the data attribute:
# app/assets/javascript/home.coffee
$ ->
$('div[data-user-id]' ).each ->
userId = $(this).data('user-id')
$(this).text(userId)
This post was inspired by a question on StackOverflow. See the original discussion.