AJAX with JQuery: html & js VS js.erb?

I’ve heard mixed opinions on this topic. As I researched, I realized there are many ways to accomplish the same thing, so I’d like to hear what the mentors think.

I have a form that POSTs via AJAX. I want to return and render the results to the view when the request completes.

I could do the following with my respond_to block:

  • Return JSON, parse the JSON with JQuery and build HTML in the view.
    Seems ugly and I don’t get to take advantage of Rails helpers.
  • Use a respond_to block and js.erb file, with some JQuery to append a
    rendered partial to the view.
  • Use respond_to block, and return only HTML. Append the HTML to the
    view with JQuery.

I’ve included a sample of the last two in the list above. Both work, but the HTML & JS version doesn’t have the odd js.erb file, so I’ve opted to use it for now.

HTML & JS

create.html.erb

<%= render :partial => 'animation', :locals => { :animation => @animation } %>

animation_controller.rb

respond_to do |format|
  format.html {render :layout=> false}
end

animation.js

  $('#new_animation').bind('ajax:success', function(xhr, data, status) {
    $('#animations').append(data);
  });

JS.ERB

create.js.erb

$lastAnimation = $('<%=j render :partial => 'animation', :locals => { :animation => @animation } -%>')
$('#animations').append($lastAnimation)

animations_controller.rb

respond_to do |format|
  format.js
end

Thoughts?

We’ve been using the technique of returning JS and HTML on the wire like your create.js.erb example and have had success with it.

You can use a few of the rails view helper shortcuts to reduce the code in your view:

$('#animations').append('<%= j render 'animation', animation: @animation %>')

I think its a solid approach. Keeps the JS organized, and all you need to do in the form is use remote: true and you’re good to go.

Hey, thanks for that helper. It cleans the file up a lot.

js.erb files seem controversial. Some believe they “fragment the logic in the view” or violate the single responsibility principle.

Since I probably don’t know what I’m talking about, could you think of an example where you wouldn’t use the js.erb, and opt for js + json, or something else?

If you had asked me about .js.erb files 6 months ago I would have tended to agree with this. After seeing DHH speak at Rails Conf 2013 on Basecamp’s Application Architecture it seemed like it was worth giving it a shot.

With that said I think there are limits to what you can achieve with this approach. Once you start moving away from the “document” approach and have persistance across multiple models, or interactions with several endpoints, it might be time to start looking into a js framework (Ember, Angular, Backbone, etc).