BeachRunnerFred
BeachRunnerFred

Reputation: 18558

My Rails app is crashing because it's loading every JavaScript file, including ones that aren't related to the page being loaded

I'm diving into Ruby on Rails and I'm building an app that uses Rails 3.2.8. I'm still learning to use the Asset Pipeline, but I'm already running into a problem. I have my Javascript files organized and named by the different pages in my website (i.e. home.html -> home.js, parts.html -> parts.js), but my Rails app is loading all my Javascript files and one of my Javascript files is crashing because it's referencing elements that don't exist on the page that's loaded (home.html)...

"uncaught exception: jsobj.edit can't find div #parts_list"

Following the online documentation, I'm including in the manifest all the JS files that are needed in my app...

//= require modernizr-latest
//= require jquery
//= require jquery_ujs
//= require home
//= require parts
//= require_tree .

...so when I load the home page, the parts.js files is loaded and executed and crashing since the parts_list div doesn't exist on the homepage.

My questions are...

  1. Should I attempt to address this problem at the Javascript level? If so, how?
  2. Or should I attempt to fix it at the Rails level and only include Javascript files that should be running at any given time. Again, if so, how can I approach this?
  3. This seems like this would be a fairly common problem. Am I'm not using Rails correctly?

Thanks so much in advance for your wisdom!

Upvotes: 1

Views: 339

Answers (3)

VenkatK
VenkatK

Reputation: 1305

To include specific javascript files into specific view pages only, you need to go with the following procedure.

i) In the assets folder create a separate folder eg. 'separate_view' , and inside put your specific js, and css files.

ii) In the application lay out write like following for 'separate_view'.
  <%= yield :separate_view %>

iii) In your target template write the following for 'separate_view'.
  <% content_for (:separate_view) do %>
    <%= javascript_include_tag "xxx.js" %>
    <%= stylesheet_link_tag "xxx.css" %>
  <%end%>


The above will go fine with your specific view files.

Upvotes: 4

Dmitry Frenkel
Dmitry Frenkel

Reputation: 1756

  1. Yes. You should solve this by not relying on DOM elements to be present when script loads. Typically, scripts are declared at the top of the page and therefore they load BEFORE any of the DOM elements are rendered by the browser. If you are relying on DOM to be present at the time script executes, you are bound to have problems. Instead, you should fix that by wrapping functionality in question into a method / function and executing this function on $(document).ready or by binding live() events

  2. Yes. You can fix that by building multiple manifest files (instead of one gigantic application.js that is included by default)

  3. This problem is commonly solved by combination of (1) and (2)

Upvotes: 0

jefflunt
jefflunt

Reputation: 33954

To answer your questions:

  1. You could do it this way, but it's not strictly necessary, and you can load assets on a per-view basis so you can get them loaded only when you want to. The key is understanding the manifest file you've got there, and when it's loaded.
  2. Yes, do this. RailsCasts episode #279 explains the loading of assets. It also touches on how to separate out your assets to only be loaded when you need them. The short version is that the manifest file is loaded in your layout, so if you use a different layout for different sections of your site, you can control which assets are loaded for which views fairly easily.
  3. You're using Rails correctly, but learning the AssetPipeline is a common, sometimes steep learning curve for a lot of people. That Railscast episode, and a lot of practice, is my best recommendation.

Upvotes: 1

Related Questions