Can I use ordinary JavaScript in CoffeeScript file? - javascript

I am trying to add some JavaScript code in my Ruby on Rails application. I have already created for me, some js.coffee files for each view in my assets. Since, I am not familiar with the CoffeeScript I just passe some ordinary JavaScript/jQuery line in the file, such as:
if ($('#cart').length == 1) { $('#cart').hide("blind", {direction: "vertical" }, 1000); }
$('#cart tr').not('.total_line').remove();
but the following error was thrown:
Error: Parse error on line 1: Unexpected 'POST_IF' (in
/home/gotqn/Aptana
Projects/depot/app/assets/javascripts/carts.js.coffee)
The source is pointed on
Showing /home/gotqn/Aptana
Projects/depot/app/views/layouts/application.html.erb where line #6
raised:
and in this file on line #6 I got:
<%= javascript_include_tag "application" %>
I am new in Ruby on Rails, but what I suppose is happening is that I am not able to write simple JavaScript in the CoffeeScript. If this is true, can I only remove the .coffe extension and be sure that the Rails magic will work and load the file?

From the docs on coffeescript.org:
Hopefully, you'll never need to use it, but if you ever need to intersperse snippets of JavaScript within your CoffeeScript, you can use backticks to pass it straight through.
So yes, you can use JavaScript in CoffeeScript - just surround it in backticks:
`function greet(name) {
return "Hello "+name;
}`
# Back to CoffeeScript
greet "Coffee"
# => "Hello Coffee"
hello = `function (name) {
return "Hello "+name
}`
hello "Coffee"
# => "Hello Coffee"
It's highly advisable that you just convert your code to CoffeeScript instead, though.

Related

Coffesscript variables in ruby code pieces

I'm just trying to call rails helper from my coffeescript.
The problem is that coffee variables are unavailable in ruby code pieces that are in <%= ... %> blocks. And if they are processed with #{} it translates to JS in a wrong way.
So, let me illustrate. This is a piece of .js.coffee.erb file:
<% environment.context_class.instance_eval { include InputsHelper } %>
$('#input_input_type').change ->
t = $('#input_input_type').val()
$('.input_address .help-block').html('<%= input_type_hint(t) %>')
This code produces such error: undefined local variable or method 't' for #<#<Class:0x007f5e75ebd860>:0x007f5e785d1410>
Ok, let's put 't' into #{}:
<% environment.context_class.instance_eval { include InputsHelper } %>
$('#input_input_type').change ->
t = $('#input_input_type').val()
$('.input_address .help-block').html("<%= input_type_hint(#{t}) %>")
This translates to JS in a wrong way. The last string looks like this:
$('.input_address .help-block').html("<%= input_type_hint(" + t + ") %>");
Quotes are broken, so it causes rails to fall with the error:
syntax error, unexpected ';', expecting ')' ; _erbout.force_encoding(__ENCODING__) ^
In that way I don't know how to manage with this. Is there any way to do it?
There is no easy way to do this.
The problem is that the coffee script executes in the browser, but the stuff in the <%= ... %> executes on the server while the server builds the coffeescript.
So when you say input_type_hint(t) this is running on the server, but the poor sad server doesn't have a clue what "t" is.
To make this work you are going to have recode the entire input_type_hint method in coffeescript, so that it can run in the browser too! (and then it won't be in the <%= => thingy.
By the way you might want to check out http://ruby-hyperloop.io as instead of using coffeescript you just write ruby everywhere, and you basically don't need this clumsy ERB business.

Integration tests with Javascript through Test::Unit and Capybara in Ruby on Rails

With RSpec and Capybara, I used to write the following code to test for features in pages that had some javascript going on:
feature "Some Feature" do
scenario "testing some scenario", js: true do
# code
end
end
Now, using Test::Unit with Capybara, how do I achieve the same result? 'Cause when I do test 'checks some feature on some scenario', js: true it doesn't seem to work.
EDIT
So, I was able to workaround with the following:
setup do
Capybara.current_driver = Capybara.javascript_driver
end
teardown do
Capybara.current_driver = Capybara.default_driver
end
test 'checks some feature on some scenario with javascript goin on' do
# code
end
Is there any other solution without such a boilerplate code?
Ok, I end up resolving that by defining a method in test_helper.rb that wraps the test within the capybara driver assigning:
def js
Capybara.current_driver = Capybara.javascript_driver
yield
Capybara.current_driver = Capybara.default_driver
end
And using it like:
test 'checks some feature on some scenario with javascript goin on' do
js do
# code
end
end
I read that minitest-data could be of use here, but I didn't dig out any further.

How can I use callback when output was printed to stdout in ruby

I am writing scripts for watching servers status.
I can write the code in javascript, but I have to write it in ruby.
In javascript,it can be done using node.js like this.
var iostat = require('child_process').spawn("iostat", ["-w 1"]);
iostat.stdout.on('data', function (data) {
console.log(data);
});
This code executes iostat command and output to console every second.
How can I implement the same thing in ruby?
In other words, I want to use callback when stdout was printed in ruby.
There are probably better ways to do this, but you can do things like this:
module PutsWatcher
def puts(string)
super("***#{string}***")
end
end
$stdout.extend PutsWatcher
puts "here"
# => "***here***"
It's a little weird if you do this in IRB or Pry, because they produce output themselves, on top of your own (i.e. the nil after you do puts), but here's a copy/paste from pry:
pry(main)> module PutsWatcher
pry(main)* def puts(string)
pry(main)* super("***#{string}***")
pry(main)* end
pry(main)* end
=> nil
pry(main)> $stdout.extend PutsWatcher
***=> #<IO:<STDOUT>>
***
pry(main)> puts "yo"
***yo***
***=> nil
***
pry(main)>
By the way, I'm not advising you do this... patching core classes is generally a bad idea. I mention it purely for academic purposes.

Remove javascript console sentences from source using gsub

Im noob in ruby and i coding a simple rakefile ...
one of my task remove from javascript files the "console" lines, what do you thing about the current snippet?
def self.remove_debug()
FileList[File.join(DIST_DIR, '**/console-nodebug.js')].each do |file_name|
puts "file: #{file_name}"
content = File.read(file_name).gsub(/console\..*?;/m, "// console removed")
File.open(file_name, 'wb') { |file| file.write(content) }
end
end
its fine?? i need to change something?
i test the code and all goes fine, but ... im looking for good practices ...
thks!
I would recommend having a debug variable and have ruby initialize that variable (I really don't know much about ruby, I leave this to you, I guess something like injecting it in the html file). And then in you js file you may do like this:
if (debug) {
console.log("I'm debugging! Yay!! XD");
}
In my humble opinion this is better than modifying the file.
Hope it helped, good luck!
==EDIT==
If it's a minified file that you need to shrink I would suggest replacing your regex bu "/* console removed */" instead of "// console removed", just in case that there is some more code after that line.
Other than that I think you will be ok. Is it working?

ruby/rails equivalent to javascript decodeURIComponent?

I have some content (html) that is being encoded as a result of this javascript (from this page) and sent to my rails application:
function encode_utf8_b64(string) {
return window.btoa(unescape(encodeURIComponent(string)));
}
The correspond js code to get it back to original is this:
function decode_utf8_b64(string) {
return decodeURIComponent(escape(window.atob(string)));
}
My question is, is there an equivalent in ruby of decodeURIComponent()? So far I have this that gets it part of the way out, but I'm missing the last step of decodeURIComponent:
CGI::escape(Base64.decode64(string))
URI.unescape could probably help:
def decode_utf8_b64(string)
URI.unescape(CGI::escape(Base64.decode64(string)))
end
you have to add the necessary rubygem too:
require 'uri'
I've tested this on ruby 1.9.2.

Categories