How to store in localStorage in Javascript from Ruby variable - javascript

I try to store a token in my localstorage from a ruby variable,
As I understood, you can only set LocalStorage with Javascript,
So here is my question, how can I pass my variable from Ruby to Javascript ? I saw some answers with script tag in the view, but is there any solution to do it directly in the app.js folder ?
So here is my Controller :
#token = HTTParty.post('https://test.pro/2.0/auth/token/access',
body: {
client_id: XXX,
client_secret: "YYYYYYYYYYYYYY",
code: LLLLLL
}
)
And in my view if I do a <%= #token %>, I have the following result :
{"access_token": "1VwCAjhsfCsdEoBoQs1G9kLHKoWOcJjamyj1s8_NQPrHeGNagzYYFrXKp_VlY", "token_type": "Bearer"}
Thanks for your help !

If you want to perform javascript from within a ruby file you can use a javascript_tag:
https://apidock.com/rails/ActionView/Helpers/JavaScriptHelper/javascript_tag
An example of how to use it:
Accessing Ruby objects in javascript
In your case, something in your view like:
<% javascript_tag do %>
localStorage.setItem('accessToken', <%= #token["access_token"] %>);
localStorage.setItem('tokenType', <%= #token["access_token"] %>);
<% end %>
Should do the trick

Related

Passing variable to Javascript doesn't work in Rails 4.2

I have just created a simple Rails 4.2 application to upload file to S3. I'm trying to follow this article https://devcenter.heroku.com/articles/direct-to-s3-image-uploads-in-rails#submitting-and-rendering-the-images and it looks like in javascript <%= #variable %> gets parsed as string.
I tried this.
This is what I have in /users/new
# GET /users/new
def new
#s3_direct_post = S3_BUCKET.presigned_post(key: "uploads/#{SecureRandom.uuid}/${filename}", success_action_status: 201, acl: :public_read)
#user = User.new
end
And this is what I tried in application.js
window.vaz = <%= #s3_direct_post.url %>;
but when I do console.log(window.vaz); I get "<%= #s3_direct_post.url %>" instead of the real value.
I tried gon as well but gon has a lot of issues with Rails 4.2
I verified that #s3_direct_post.url returns something in the console.
Add .erb extension to application.js file (application.js.erb). <%= => is erb syntax and you need to process it as erb file first so that <%= #s3_direct_post.url %> is evaluated as ruby code.
http://guides.rubyonrails.org/asset_pipeline.html#preprocessing

Iterate through array passed from controller

I'm using Ruby on Rails.
Here is my code for the view, where I make a post to the controller, passing parameter "tplangroup.id":
<div id="collapse">
<%= form_tag(tplans_collapse_tplans_path, :method => 'post', :remote => true ) do %>
<%= hidden_field_tag(:tplangroup_id, tplangroup.id) %>
<% end %>
</div>
Here is my code on the controller end, where it parses the necessary data and shoots back array "#ordered_tplans"
def collapse_tplans
#collapsed_tplangroup = Tplangroup.find(params[:tplangroup_id])
tplans_from_tplangroup = #collapsed_tplangroup.tplans
#ordered_tplans = tplans_from_tplangroup.order("favrank DESC")
return #ordered_tplans
end
Since I called :remote => true in the original form located in the view, it passes this array to a file called "collapse_tplans.js"
My question is: what is the best way/practice to parse through this array now passed to the js file, and display its contents in the view? Do I use rails code in the js file to manipulate the object? Or do I do it all in javascript/jquery? What is the best practice, and could you provide any example?
Thanks!
Really kind of depends on how you want to go about it, as with all code, there are many ways to skin a cat. I find the easiest way is to use the return ujs as an erb file (collapse_tplans.js.erb) and from there, choose the element on the page you want to attach the retuned object to, and call a standard erb or haml partial where your iterations can be done clearly.
e.g.
In collapse_tplans.js.erb
$('#my_wacky_element').append("<%= j render(:partial => 'collapse_tplans', :locals => { :ordered_tplans => #ordered_tplans }) %>");
Then in
_collapse_tplans.html.erb
<ul>
<%= ordered_tplans.each do |tplan| %>
<li><%= tplan.attribute %></li>
Here is a RailsCast on how to pass data to js from rails:
http://railscasts.com/episodes/324-passing-data-to-javascript?view=asciicast

How do I make a ruby variable accessible to a javascript file?

I have two variables, <%= #user.lat %> and <%= #user.lng %>
These variables change depending on the user whose logged into my system - it's the address the user gave when registering with my app.
In a scripts.js file I've been trying to define them, so my Google map can show with the user's latitude and longitude.
But
function initialize_google_maps() {
var currentlatlng = new google.maps.LatLng(<%= #user.lat %>, <%= #user.lng %>);
etc, etc doesn't work, because it can't understand my ruby code.
I tried defining them at the top of the scripts.js file like:
var map_latitude = "<%= #user.lat %>";
var map_longitude = "<%= #user.lng %>";
and then using:
function initialize_google_maps() {
var currentlatlng = new google.maps.LatLng(map_latitude, map_longitude);
but I've learnt that you just can't put ruby in a js file. I did try renaming it to scripts.js.erb but that didn't work either.
So, how can I define <%= #user.lat %> and <%= #user.lng %> so they'll be recognised by my scripts.js file, and show up in my maps? I did try this answer here, creating a partial, but it didn't work for me. Maybe I was doing it wrong.
Please note: I can't simply put the code and maps function between script tags in a html.erb file because I'm using some ajax, and things get messed up - the ruby variables need to be recognised by the js file. Thanks.
It's possible to use Ruby in JavaScript file, but it's not recommended so I will not explain how.
To answer your question, you can just put the variable in your HTML attribute:
<div id="foo" data-lat="<%= #user.lat %>">Books are coming soon!</div>
And then extract it with JavaScript:
var lat = $("#foo").data("lat");
http://railscasts.com/episodes/324-passing-data-to-javascript will get you going in the right direction.
I think unobtrusive javascript is probably a good way to do this:
http://railscasts.com/episodes/205-unobtrusive-javascript
As the others suggested, you should aim for unobtrusive javascript.
Yet, you might want to use embedded javascript code in a js response for a view, for example. In this cases, you should use the erb extension in your javascript files, so the correct is.js.erb.

How to make a global JavaScript File for Ruby on Rails 3which gets some content from Rails with <%= ... %>

I have a model with lots of parameters and a function giving all the parameter names. Now I'd like to have a global Javascript file using this function like this
function bar() {
<% Model.parameter_names.each do |name|
parameters.push("<%= name %>");
<% end %>
// do something with them
}
The *parameter_names* method is a Class Method (*def self.parameter_names*), so i do not need an object.
Is this possible?
You can, sort of.
First of all, if you are thinking about a javascript file included like this :
<script src="your-js-file.js"></script>
You can forget about it. In no way, RoR is doing anything for that file.
You can mix javascript with RoR in controller responses because that js file is read by RoR, then evaluated for any Ruby expressions, then returned as the response to your browser. In fact, if you take a look at the js response from the controller for something like you wrote :
function bar() {
<% Model.parameter_names.each do |name|
parameters.push("<%= name %>");
<% end %>
// do something with them
}
you would see something like :
function bar() {
parameters.push("abc");
parameters.push("def");
parameters.push("ghi");
parameters.push("jkl");
}
Javascript is a client side technology. The only way to add server side code in it is to actually generate the js file with server side code. This is probably your best shot at it.
Controller :
def jsfile
#variable = "hello, world!"
respond_to do |format|
format.js
end
end
jsfile.js.erb
function bar() {
alert('<%= #variable %>');
}
Include the javascript file like this :
<script src="<%= jsfile_controllername_path %>"></script>
And add the corresponding route in routes.rb
Create the Javascript array in the head of your layout and then reference that in your global JS file.
Layout example (HAML):
%html
%head
:javascript
var parameter_names_array = ['#{Model.parameter_names.join(', ')}'];
Global JS file
function bar() {
// do something with "parameter_names_array"
}

Weird JSON Javascript problem in Rails

I'm trying to get my JSON from my controller to my view. In my controller I am doing:
#nodes = Node.all
#json = #nodes.as_json(:only => [:ID, :Lat, :Lon])
In my view I have tried:
1) var stuff = <%= #json %>
2) var stuff = <%= #json.to_json %>
3) var stuff = <%= #json.to_json.to_json %>
and all of those give me an error. I usually get an "Unexpected Syntax Error &" or "Unexpected Syntax Error {"
I have also tried using jquery and using respond_to within the controller, but that doesn't seem to work either.
My thoughts are that getting json to the view shouldn't be a big issue and shouldn't require jQuery, and currently, my page source looks like:
var stuff = [{"node":{"ID":1301499692582,"Lat":42.3605063113369,"Lon":-71.0870862191138}},{"node":{"ID":1301499691515,"Lat":42.3605147089149,"Lon":-71.0870533282532}},{"node":{"ID":1301431075499,"Lat":42.3605456103,"Lon":-71.0875239075536}} etc
I dont understand the &quot symbols (maybe thats where the syntax error is coming from) but when I do render :json => #nodes.to_json, the page renders a normal json that is valid:
[{"node":{"ID":1301499692582,"Lat":42.3605063113369,"Lon":-71.0870862191138}},{"node":{"ID":1301499691515,"Lat":42.3605147089149,"Lon":-71.0870533282532}},{"node":{"ID":1301431075499,"Lat":42.3605456103,"Lon":-71.0875239075536}}
Note: I've also tried doing var stuff = '<%= #json.to_json %> but when I do var json = JSON.parse(stuff), it gives me an illegal token error.
Can someone please help me with this? Thanks so much!
This is Rails html-encoding your string as is default in Rails 3.
You need to mark your JSON as html_safe:
var stuff = <%= #json.to_s.html_safe %>
Note that .to_s is needed because as_json gives Hash instead of string. You could do this instead:
# in controller
#json = #nodes.to_json(:only => [:ID, :Lat, :Lon])
#and in view
var stuff = <%= #json.html_safe %>
I think you need to put quotes around it, then you can ask jquery to parse the string into JSON.

Categories

Resources