Rails leaflet map geosearch stopped working after precompiling assets - ruby-on-rails

I'm using meijer's geosearch in a leaflet map. It was working fine but I've suddenly broken it and I don't know how. The maps still appears, but the search box doen't appear in the map. The code that breaks the app is (leaflet_map.js):
new L.Control.GeoSearch({
provider: new L.GeoSearch.Provider.OpenStreetMap(),
showMarker: false,
position: 'topright',
retainZoomLevel: false
}).addTo(map);
I don't think it can find the geosearch js or css files, even though I've clearly included them in application.html.erb:
<%= stylesheet_link_tag "leaflet.css" %>
<%= javascript_include_tag "leaflet.js" %>
<%= stylesheet_link_tag "l.geosearch.css" %>
<%= javascript_include_tag "l.control.geosearch.js" %>
<%= javascript_include_tag "l.geosearch.provider.openstreetmap.js" %>
I think the turning point might have been when I typed bundle exec rake assets:precompile at the command line (I also did RAILS_ENV=production bundle exec rake assets:precompile). Why would that break geosearch?
I have deleted my public/assets folder, but that didn't make any difference.
Also, the console doesn't show any complaints about broken geosearch.js files or not finding them. I am, as usual, baffled.
js console:
Uncaught Error: Map container not found.
Uncaught TypeError: Cannot read property 'Provider' of undefined
Mixed Content: The page at 'xxxx' was loaded over HTTPS, but requested an insecure image 'http://a.tile.openstreetmap.org/13/7424/5131.png'. This content should also be served over HTTPS.
view:
<div id="map-leaflet"></div>
<%= javascript_include_tag "easy-button" %>
<%= javascript_include_tag "leaflet_map" %>
leaflet_map.js
map = L.map('map-leaflet', {center: [10.0, 10.0], zoom: 16} );
map.options.maxZoom = 22;
L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 22
}).addTo(map);
// add location search box
new L.Control.GeoSearch({
provider: new L.GeoSearch.Provider.OpenStreetMap(),
showMarker: false,
position: 'topright',
retainZoomLevel: false
}).addTo(map);
Demo site here

Your leaflet-map init code is being included twice, once inside <script src="/assets/leaflet_map-8e1007491534b1245e2ccc867a845d14e60679a58ca180c5e9cbef68530aa571.js"></script>and once from application.js. Drop the leaflet-map asset reference underneath your map div to begin working through these problems.

Related

How to include a manifest.json file in rails?

I have following html code in a view whose layout is false.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link rel="manifest" href="manifest.json">
Jquery is being loaded but not the manifest.json, when I view page source and look at them I get this error:
No route matches [GET] "/manifest.json"
Even though I have included manifest.json inside the javascripts folder inside assets folder.
I also tried
<%= javascript_include_tag "manifest.json" %>
but that didn't work either..and that get routes error
I tried
<%= manifest_link_tag "manifest" %>
Again that didn't work out, gave error :
undefined method `manifest_link_tag'
I also added the manifest.json inside initializers/assets.rb but still no luck!!
I think you need to include it like this:
<link rel="manifest" href="<%= asset_path 'manifest.json' %>">
My solution is:
= tag(:link, rel: 'manifest', href: some_path)
or
= tag(:link, rel: 'manifest', href: asset_path('manifest.json'))

Rails 2.3.14 No Route for .js.erb File

In my layout footer I am including page specific JavaScript files like so:
<%= javascript_include_tag "#{params[:controller]}_#{params[:action]}" if javascript_exists?("#{params[:controller]}_#{params[:action]}") %>
The helper I am using is from another question on this site but modified to work with Rails 2:
application_helper.rb
def javascript_exists?(script)
script = "#{RAILS_ROOT}/public/javascripts/#{script}.js"
extensions = %w(.coffee .erb .coffee.erb) + [""]
extensions.inject(false) do |truth, extension|
truth || File.exists?("#{script}#{extension}")
end
end
Then I also init the included file:
<script>
jQuery(document).ready(function() {
<%= "#{params[:controller].titleize}#{params[:action].titleize}.init();" if javascript_exists?("#{params[:controller]}_#{params[:action]}") %>
});
</script>
This works perfectly fine if my file is named controller_action.js but once renamed to controller_action.js.erb Rails generates an error because it can't find it.
GET http://localhost:3000/javascripts/controller_action.js 404 (Not Found)
Uncaught ReferenceError: ControllerAction is not defined
Update
If I use the .rjs extension then there are no errors generated but this seems to be because Rails doesn't think the file exists. (I updated the javascript_exists? with the .rjs extension.)
After some more debugging, the file is being located:
/path/public/javascripts/circuit_list.js true
but this returns false if .rjs is used.
The routing error when navigating to http://localhost:3000/javascripts/controller_action.js in the browser is:
No route matches "/javascripts/controller_action.js" with {:method=>:get}

Getting Dojo to Work with Ruby on Rails 4

I'm porting my symfony app to Ruby on Rails 4.2.0. My setup works fine in symfony. There is this old post on how to use dojo with RoR, but it uses deprecated code.
In my application.html.erb I have
<script>dojoConfig = {async: true}</script>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>
I replaced the symfony wrappers with Rails ones. I also changed the dojo version. I was using 1.9.1. Rails generates this html:
<script>
dojoConfig = {async: true}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js">
The last line is followed by a bunch of compressed javascript and the close script tag in Firebug.
I didn't make any changes in my home/index.html.erb where I'm testing this code. In app/assets/javaascipts/home.js, I have:
//require(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip)
define(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip)
{
ready(function()
{
var head = "<div class='footnote-text'>";
var tail = "</div>";
var fnt1 = head + dom.byId("fnb1").innerHTML + tail;
var fnt2 = head + dom.byId("fnb2").innerHTML + tail;
var fnt4 = head + dom.byId("fnb4").innerHTML + tail;
new Tooltip({ connectId: ["footnote1"],position:["after","above","below"],label: fnt1 });
new Tooltip({ connectId: ["footnote2"],position:["after","above","below"],label: fnt2 });
new Tooltip({ connectId: ["footnote4"],position:["after","above","below"],label: fnt4 });
new Tooltip({ connectId: ["footnote5"],position:["after","above","below"],label: fnt4 });
});
});
//require(["dojo/dom", "dojo/ready", "dijit/Dialog"], function(dom, ready, Dialog){
define(["dojo/dom", "dojo/ready", "dijit/Dialog"], function(dom, ready, Dialog){
ready(function(){
var fnt3 = dom.byId("fnb3").innerHTML;
myDialog = new Dialog({
title: "Contact Me",
content: fnt3,
style: "width: 300px"
});
});
});
The commented out require lines are what I use in my symfony app. As you can see, I replaced them with define as described on the dojo site. When I run it, I get the following error on the Firebug console:
ReferenceError: define is not defined
...define(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip
If I used require instead of define, I get require is not defined.
Update
I tried installing dojo into the app and made some progress. I copied the download from dojo to vendor/assets/javascript/dojo. The dojo directory contains the subdirectories dojo, dojox, and digit
I then added
//= require dojo/dojo/dojo.js
to app/assets/javascript/application.js. I also changed the define back to require in the home.js file. When I reloaded the page, I got an error complaining that it couldn't find Tooltip. I then added:
//= require dojo/dijit/Tooltip.js
On reload it complained about a bunch of other missing js files. This is the same problem I had using symfony, which is why I went to the google image. How can I get to rails to search for the files in the vendor directories? This is one of the errors:
"NetworkError: 404 Not Found - http://amcolan.loc/dijit/_base/manager.js"
Update 2
Since require_tree worked for app assets, I thought it might work to vendor as well. I added
//= require_tree ../../../vendor/assets/javascripts/dojo
to my application.js file. When I reloaded the page, it took about a minute. My guess is that it's loading everything in the dojo directory tree, which is not surprising. The page load completed without any errors. When I hovered over a tooltip item (the purpose of the code is to show tooltips), Firebug cranked out about two thousand errors and quit. All the errors appear to be "ReferenceError: define is not defined"
Update 3
I went back to using the googleapi. My application.html.erb header looks like this
<head>
<meta charset="UTF-8">
<title><%= content_for?(:title) ? yield(:title) : "American Colonial Ancestors" %></title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<script>dojoConfig = {async: true}</script>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
I reversed the order of the javascript includes. The page reloaded without errors. The tooltip doesn't work, but it doesn't generate any errors when I hover over an item. I put a bad statement in the home.js code and it came up on the console so I know the code is being parsed. I may just have a bug in my page setup.
There may be more than one way to get Dojo toolkit to work with Ruby on Rails. This is the easiest if not the most efficient way. This works in Rails 4.2.0. I would imagine it would work in other versions as well.
In views/layouts/application.html.erb add the following prior to the inclusion of the site scripts:
<script>dojoConfig = {async: true}</script>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>
Change the version to the latest or to which ever one you want to use. Here I'm using version 1.10.3. The dojo site says there are other CDN's (Content Delivery Network) for the source code. I'm using google as it was in their example. Here are the pertinent parts of my head section:
<head>
<meta charset="UTF-8">
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= stylesheet_link_tag "http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dijit/themes/claro/claro.css" %>
<script>dojoConfig = {async: true}</script>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= content_for :page_script %>
<%= csrf_meta_tags %>
</head>
If you are going to use any of the toolkit's dialog boxes, tooltips, etc, you will need to include a stytlesheet by adding something like this:
<%= stylesheet_link_tag "http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dijit/themes/claro/claro.css" %>
Change the version and the theme to your own requirements. Here I'm using the claro theme. You can see it in my head section above. I don't think placement is critical. You also need to declare your theme class in the body statement. Here's mine:
<body class="claro">
An older post on the subject had different javascript formatting. I don't think anything special is needed. Here's an example of a working script:
require(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip)
{
ready(function()
{
var head = "<div class='footnote-text'>";
var tail = "</div>";
var fnt1 = head + dom.byId("fnb1").innerHTML + tail;
var fnt2 = head + dom.byId("fnb2").innerHTML + tail;
new Tooltip({connectId: ["footnote1"], position:["after","above","below"], label: fnt1 });
new Tooltip({connectId: ["footnote2"], position:["after","above","below"], label: fnt2 });
});
});
As mentioned in my question, I tried placing the Dojo Toolkit source in vendor/assets/javascript. Starting with with version 1.7, dojo started using Asynchronous Module Definition (AMD). It may be the case that the AMD loader is incompatible with the Rails pre-compile feature. I don't know enough about it to say for sure.

Cached app issue - deployed with capistrano

I have deployed my app for first time. Cap deploy was successful. However I was getting an error on a specific code segment. So I decided to delete this code segment and get the website up and running first before fixing this error.
I run cap deploy again but I am still getting the same error on the code segment that I removed from the source file (I see the error by tailing production.log). It was not suppose to be there. I searched around on the net and found that the problem is that there is a cached version of the app. I found out that a solution would be to delete the cache-copy folder in /shared folder.
I restarted my services (nginx, unicorn) and open the site again and I still get the same error on the code segment I removed.
I checked my new current folder, cached-copy folder and last release folder and all don't have the code segment that produces the error.
It's really odd to me. Any clue whats going on?
Thanks!
Code segment that produces the error:
ActionView::Template::Error (undefined method `stripe' for #<Rails::Application::Configuration:0x00000002a85578>):
20: <meta name="viewport" content="width=device-width">
21: <%= javascript_include_tag 'application' %>
22: <%= javascript_include_tag "https://js.stripe.com/v1/", type: 'text/javascript' %>
23: <%= javascript_tag "Stripe.publishableKey = '#{Rails.configuration.stripe[:publishable_key]}';", type: 'text/javascript' %>
24: <%= csrf_meta_tag %>
25: <%= stylesheet_link_tag "application", :media => "all" %>
26: <script type="text/javascript" src="//use.typekit.net/xoh2pss.js"></script>
app/views/layouts/application.html.erb:23:in `_app_views_layouts_application_html_erb__486989174473553269_34754060'
The line 23 was removed but its still shown as generating the error.
# config/initializers/stripe.rb
Stripe::API_KEY = 'asd8df9sadf766'
# application.html.erb
<%= javascript_tag do -%>
Stripe.publishableKey = <%= Stripe::API_KEY %>;
<% end -%>
Are your assets precompiled and the old all.js (or similar) being redeployed without this change present? If the routine invoked by the javascript portion isn't present that could produce an error -- that might be the stripe method you're trying to invoke. If they were manually precompiled and you made the change but didn't re-compile it, the redeploy would simply put the old one back out there.

Content for doesn't work in production mode

On one of application's page there is:
<% content_for :head do %>
<%= tag :meta, property: "fb:app_id", content: ENV["FACEBOOK_APP_ID"] %>
<% content_for :title, #check.title %>
<% end %>
And it worked in development, while I was running server at my localhost.
After that I deployed application on heroku. And that simply doesn't work.
What means doesn't work. I load page in development at localhost:
<title>Tenta</title>
<meta content="*****************" property="fb:app_id">
When I load this page deployed at heroku host, these tags are simply absent.
Why?
Also, If you don't know this particular issue solution, I would appreciate if you adivce me, how can I look what is going on - heroku logs and watching last 150 logs in inconvinient windows console doesn't give me a lot of helpful information.

Resources