The following is not a problem per se, because it can be avoided by not using the same name for two asset pipeline files. I am simply curious about an explanation, so thanks for any insight.
This is Rails 3.2.6, sprockets 2.1.4 (also tried with latest, 2.4.4). A minimal example: http://github.com/richardkmichael/js-test
I have a FooController, and am writing javascript not coffeescript, so I've created a new file foo.js, but left an empty foo.js.coffee.
I have a setInterval() function (testing readyState === 'complete') which is stopped with clearInterval(). However, the interval function loops, as if the clearInterval() call is not working.
When I remove the empty foo.js.coffee file, the looping stops and the JS works as expected. Replacing the empty foo.js.coffee starts the looping behaviour on the client again.
The server-side processing appears to be changing something client-side, causing a reset/new interval timer?
There does not appear to be a client-side JS difference between these two cases. However, in Chrome's web inspector:
'Resources' lists
foo.jsonce and in both cases contains exactly the JS as it appearsfoo.jsserver-side.application.jscontains a single semi-colon. (Aside, this looping behaviour remains even if I remove jQuery.)'Sources' (localhost / assets) lists
foo.js?body=1twice.
app/controllers/foo_controller.rb:
class FooController < ApplicationController
def index
render :inline => '<p>Hello, World!</p>', :layout => true
end
end
app/assets/javascripts/foo.js:
var readyStateCheckInterval = setInterval(function () {
if (document.readyState === 'complete') {
console.log('Document ready.');
clearInterval(readyStateCheckInterval);
}
}, 2000);
app/assets/javascripts/foo.js.coffee:
<empty -- just `touch .../foo.js.coffee`>
A (perhaps) similar question: sprockets duplicate file naming
UPDATE
Based on the responses, I noticed there were two <script> tags (rather obvious in hindsight). Testing Frederick's explanation, I changed the javascript to avoid losing the first timer reference, and it "works" (exactly two writes to console.log) as expected.
/*jslint indent: 2 */
(function () {
'use strict';
var intervalTimers = {},
date = new Date(),
time = date.getTime();
function setupIntervalTimer(name) {
intervalTimers[name] = setInterval(function () {
if (document.readyState === 'complete') {
console.log('Document ready.');
clearInterval(intervalTimers[name]);
}
}, 2000);
}
setupIntervalTimer(time);
}());
<script>tags in the case where bothfoo.jsandfoo.js.coffeeexist?