Ruby on Rails asset pipeline doesn't work properly - javascript

I have been working on a ruby on rails project just now. I have created a controller named 'animals' and a view (index.html.erb) for index action. I don't want to include 'application' javascript file.
So I created animals.js
The file's content is
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= animals.coffee
I have also added animals.js and animals.css to asset.rb
Rails.application.config.assets.precompile += %w( animals.js )
Rails.application.config.assets.precompile += %w( animals.css )
My index.html.erb contains following lines
<%= stylesheet_link_tag 'animals', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'animals', 'data-turbolinks-track' => true %>
When I inspected source html code generated by server, I have seen that jquery scipts hadn't been included in the page. It was just animal.js file.
<head>
<meta name="viewport" content="width=device-width, initial- scale=1.0">
<title>Rails Omniauth</title>
<meta name="description" content="Rails Omniauth">
<link rel="stylesheet" media="all" href="/assets/animals.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b5433a495991b7852b855.css?body=1" data-turbolinks-track="true">
<script src="/assets/animals.self-1d93d37bf2f830ac42e82eb68e3bb0040ece5d23533a05bf77f7407fd59178d3.js?body=1" data-turbolinks-track="true"></script>
</head>
Any suggestions why these scripts had been inclued ?
Thanks.

I think your issue might be that you have two files with the same name (but different extensions). Since the Rails asset helpers treat coffescript and js files equally this is ambiguous:
<%= javascript_include_tag 'animals', 'data-turbolinks-track' => true %>
Which file should it load? I'm guessing it takes the first in alphabetical order which would be animals.coffee.
To solve the issue move the sprockets manifest to animals.coffee and remove the animals.js file.
# app/assets/animals.coffee
#= require jquery
#= require jquery_ujs
#= require turbolinks
#= require bootstrap-sprockets
#= require_self
alert 'Hello World'

You can remove the animals.coffee file and animals.js can be require in the file of application.js to available your js code in your project.

Related

Sprockets //= require with jsbundling-rails (esbuild) - how to include JS provided by gem?

Basically, exactly as the title says. I have a gem installed that gives me some JS to use. This wasn't a problem before as I was using Sprockets + Assets pipeline.
Now, I migrated to jsbundling-rails and have literally no idea how to include that JS code provided by gem. I've spent like 10 hours searching and no luck so far.
Please, help me.
The gem would have to have a js package that can be installed with yarn/npm so that it can be imported in application.js. If it doesn't, you can setup a js file to be processed only by sprockets, like in the old days.
Add another javascript entry point that will skip esbuild and will be processed only by sprockets.
Update manifest:
// app/assets/config/manifest.js
//= link custom.js
Add //= require directive:
// app/assets/javascripts/custom.js
//= require gem_javascript
Add it to layout:
<!-- app/views/layouts/application.html.erb -->
<%= javascript_include_tag "application", "custom", "data-turbo-track": "reload", defer: true %>
Alternatively, instead of using //= require add gem_javascript to javascript_include_tag:
<%= javascript_include_tag "application", "gem_javascript", "data-turbo-track": "reload", defer: true %>
Might have to add it to manifest as well for precompilation:
// app/assets/config/manifest.js
//= link gem_javascript

ReactJS and javascript not displaying on Rails 5 app

The reactJS components and javascript codes don't display on my rails 5 app. I'm using react-rails gem and some plain JS with the asset pipeline. Here's my application.js manifest:
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require react
//= require react_ujs
//= require components
//= require init
//= require page_specific
//= require rails-ujs
//= require_tree .
I have sub-directories in my javascript assets directory and have referenced them appropriately and followed the ruby assets pipelines docs but when I run the server, the navigation bar and other element aren't displaying and clicking the button doesn't work either. See the screenshot:
screenshot
My assets files setup:
screenshot 2
This is my application.html.erb file:
<!DOCTYPE html>
<html ng-app="Stories">
<head>
<title>Stories</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
<%= favicon_link_tag '', type: 'image/png' %>
<%= favicon_link_tag '', rel: 'apple-touch-icon', type: 'image/png' %>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body class="<%= controller.controller_name %> <%= controller.action_name %>">
<%= render 'layouts/overlay' unless user_signed_in? %>
<%= react_component('UserOverlay', {}) %>
<div data-behavior="progress-bar" class="progress-bar"></div>
<div class="container-fluid main-container">
<%= yield %>
<%= yield :sidebar %>
</div>
</body>
<script type="text/javascript">
window.userSignedIn = <%= user_signed_in? %>;
</script>
</html>
This is the assets.rb file:
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path.
# Rails.application.config.assets.paths << Emoji.images_path
# Add Yarn node_modules folder to the asset load path.
Rails.application.config.assets.paths << Rails.root.join('node_modules')
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
Am I missing another step?

Load custom javascript files in Rails app

I developed a javascript diagram tool (using kineticjs), and need to load some different js files. But they need to be load in order. I manage to do that this way:
inside a specific view (in the top of the file):
<%= javascript_include_tag "kinetic" %>
<%= javascript_include_tag "diagramtool/diagramtool0" %>
<%= javascript_include_tag "diagramtool/diagramtool1" %>
<%= javascript_include_tag "diagramtool/diagramtool2" %>
<%= javascript_include_tag "diagramtool/diagramtool3" %>
<%= javascript_include_tag "diagramtool/diagramtool5" %>
<%= javascript_include_tag "diagramtool/diagramtool6" %>
this in assets.rb:
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# Rails.application.config.assets.precompile += %w( search.js )
Rails.application.config.assets.precompile += %w( kinetic.js )
Rails.application.config.assets.precompile += %w( diagramtool/diagramtool0.js )
Rails.application.config.assets.precompile += %w( diagramtool/diagramtool1.js )
Rails.application.config.assets.precompile += %w( diagramtool/diagramtool2.js )
Rails.application.config.assets.precompile += %w( diagramtool/diagramtool3.js )
Rails.application.config.assets.precompile += %w( diagramtool/diagramtool5.js )
Rails.application.config.assets.precompile += %w( diagramtool/diagramtool6.js )
And the files are located in assets/javascripts/diagramtool
The problem is that they are not load in order when I move to the view that has the code above to load the files. But if I refresh the page they are load in order!
So, my questions are
How can I assure the js files are load in order?
Why the files are load in order when I refresh the page? And why they are not load in order when I navigate through the application?
There is another way to do this? I tried to do it in application.js using the asset pipeline with the "require" key word. But I don't know how to do it there.
I also tried to put all the code in one file, but the file is load before the kinetic file! And I get errors because I need to load the library file first. But if I refresh the page it works again.
Any help? I don't really know what to do, to have this working properly. I'm new at Ruby on Rails, and I'm still learning how to do this kind of "configurations".
Edit:
I'm not using the application.js to load the js files, because I wasn't able to do it that way. But here it is:
//= require jquery
//= require bootstrap-sprockets
//= require jquery
//= require jquery_ujs
//= require turbolinks
/*
require kinetic
require diagramtool
require_tree .
*/
Just solved it this way:
created a manifest file diagrams.js:
//= require diagramtool/kinetic
//= require diagramtool/diagramtool0
//= require diagramtool/diagramtool1
//= require diagramtool/diagramtool2
Added this in the view:
<%= javascript_include_tag "diagrams" %>
Using the asset pipeline with a manifest file.

rails 4 - all javascripts being included at all times

I understand the "why" part of "why do all js / css files get included in rails asset pipeline" as explained here.
However, that's not always desirable, is it? For instance, I have a non-standard layout I use just to display items that require Google maps. I don't want all the external gmap libraries included on all pages-- it's not necessary and is just wasteful-- but if I don't include them on every page, the calls to the google api in the map.js.coffee files will throw errors.
Is there a way to force the map.js.coffee ONLY show on a maps view?
There is one solution, the javascript_include_tag:
# assets/javascripts/
# user.js.coffee
# form.js.coffee
# map.js.coffee
# views/users/location.html.haml
= javascript_include_tag 'map'
But defining //= require_tree . in the assets/application.js does include all JS files, am I right?
So doing this would include the file twice, right?
Update: Following this RailsCast ( http://railscasts.com/episodes/279-understanding-the-asset-pipeline ) We might be able to create a public folder, containing all "shared" js files, and require it: //= require_tree ./public
To combine what the other answers suggested and other sources on the web advised, it seems like the best answer to this situation is to do the following:
Create subdirectories in the assets/javascripts and assets/stylesheets directories as well as maps.js and maps.css files. In my example above you'd have
app/
assets/
javascripts/
application.js
maps.js
maps/
site/
stylesheets/
application.css
maps.css
maps/
site/
Create any needed page-specific javascripts / stylesheets in those directories.
The maps.js file would look like:
//= require_tree ./maps
which will include all items in the maps directory / subdirectories.
The application.js is the same but includes the "main" site resources as well as any site-specific items:
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap
//= require_tree ./site
Create a maps layout file called views/layouts/maps.html.erb, and in the layout file, use the javascript_include_tag to change which js / css file gets parsed for includes:
views/layouts/maps.html.erb:
<%= stylesheet_link_tag "maps", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "maps", "data-turbolinks-track" => true %>
views/layouts/application.html.erb:
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
Make sure the MapsController specifies the maps layout!
class MapsController < ApplicationController
layout "maps"
Notice the line in application.html.sim:
= javascript_include_tag "application"
You want to include a different set of javascripts in a different layout map.html.slim, then create another javascript file, such as map.js.coffee, and in this file you included only files you need. Now the layout file needs to use this
= javascript_include_tag "map"

Chartkick + Rails 4 "undefined method `pie_chart' for #<#<Class:..."

I am new to Rails. I followed the documentation and this example: Using Chartkick in Rails 4.0
but I cannot get Chartkick to work. I get undefined method pie chart. My js looks like this:
//= require chartkick
//= require jsapi
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap
//= require_tree .
I have tried including the javascript_include in both the application kayout and the show page. <%= javascript_include_tag "//www.google.com/jsapi", "chartkick" %>
Any ideas? Thanks all. I really do appreciate every bit of help I get here.
It turns out that, since Chartkick runs as an engine, I did not need to add // include chartkick into the application js file- I removed it and it worked like a charm. That means that the steps to get Chartkick to work in Rails 4 are:
add gem 'chartkick' to your Gemfile
add <%= javascript_include_tag "//www.google.com/jsapi", "chartkick" %> to app/views/layouts/application.html.erb
Just add this to your chartkick's javascript_include_tag - 'data-turbolinks-track' => true. Also have a jquery-turbolinks gem installed (with it's correct structure of scripts requiring in application.js file). Finally restart the server.
write
#= require active_admin/base
require chartkick
in active_admin.js.coffee
and call direct jsapi from google like this in partial file.._items.html.ebr in app/views/items folder
javascript_include_tag "//www.google.com/jsapi", "chartkick"
pie_chart order, library: {pieSliceText: 'value'}
and then call this partial file like this
div class: 'custom-class' do
h3 'Items'
#item = Item.group(:menu_id).count #whatever data you pass to chart
render partial: 'items/items', locals: {item: #item}
end

Categories