Rails json view into javascript function - javascript

I am storing some json data in an active-record session so have created a route and controller action which renders fine in the browser but when I try and pass the route into a JavaScript function the response in browser(chrome) network tab is null
Controller
class DataFilesController < ApplicationController
def show
render json: session[:my_data]
end
end
Route
get 'data-file.json', to: 'data_files#show', as: :data_file
Javascript function (in view)
= content_for :javascript do
:javascript
accessibleAutocomplete({
element: document.querySelector('#autocomplete-wrapper'),
id: 'autocomplete',
source: openregisterPickerEngine({
url: "<%= data_file_path %>"
}),
templates: {
inputValue: inputValueTemplate,
suggestion: suggestionTemplate
}
});

The openregisterPickerEngine library uses the fetch Request object, which by default does not send cookies. This means that your DataFilesController endpoint does not get the session ID in the users cookie and the session object is null.
Request.credentials needs to be set: https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials
Unfortunately the Request object is created in the library code which you don't directly control: https://github.com/alphagov/openregister-picker-engine/blob/master/src/index.js#L294
You either need to redesign the code so that the data endpoint does not need the session, or fork or modify that library (or stop using the library and craft your own fetching and parsing code).
Edit: actually the latest version of the library uses xhr while the older version you were using calls fetch. So the simplest "solution" is to upgrade the library: unlike fetch, xhr sends cookies with same-origin requests by default.

Related

How to take some data from an outter POST and POST it again to the same app on RoR?

Basically i'm receiving some data (variables a and h) from another site, and i would like to receive them and then make a POST with that data (the a and h variables that i already received) to my self app, i know that doesn't make a lot of sense but i need to do that.
I already coded the part where i receive the data from the other site.
MyRoute
post '/', to: "pages#info"
MyController
class PagesController < ApplicationController
skip_before_action :verify_authenticity_token, only: [:info]
protect_from_forgery :except => :info
layout "second"
def info
if params[:initzarqkr].present?
#h1 = params[:h]
#a1 = params[:a]
#h1_i = #h1.to_i
#a1_i = #a1.to_i
end
end
end
My View (shown at / where the post is received)
<h1><%= #h1 %> | <%= #a1 %> </h1>
So i want to take that data i stored on the variables #h1 and #a1, re POST it to my app and then store it on some other variables in order to show them on my view at the route /, instead of the ones that i got on the post that i received from outside (even though i know that the values should be the same ).
How can i grant this?
Thanks very much for reading.
What you'r talking about sounds like a redirect. A redirect is every time a GET request within Rails. Converting a POST to GET request has some drawbacks. You have to consider all the things which are different between a GET and POST request. One of the thing is the request lenght restriction.
In my point of view you have the following options:
redirect to the wanted action and append the parameters to the redirect url
handle the request directly within info and redirect after handling without params
store the parameters within your session hash and redirect to the other action without params
use a net/http or another libraray to post within info your data to an url and use a redirect
create a view for info with a form which gets submitted automatically via javascript
If a redirect with code 307 (repost data to new url) would work within Rails, I don't know.

How can I get the current_user from Devise in Rails for JS use

I'm trying to figure out the best way to get the current_users username and id from devise in rails without having to store it in the DOM for later access. Are there any techniques/strategies to accomplish this?
While Rails is just the backend on your server and javascript is the frontend on client-side you defenitely need to put something inside html or ajax it.
a few approaches:
1.
just write it into the body with an data attribute
<body data-username="<%= current_user.username %>
2.
making an ajax call to the server to receive that information (pseudocode)
$.ready() {
$.getJSON(/api/user-information, function(data) {
username = data.username
settings = data.settings
unread_messages = data.unread_messages_count
}
}
# /api/user-information
def user_info
render json: {username: current_user.name, settings: {enabled: false, wants_chat: true}, unread_messages: 10}
end
or 3. maybe this gem is helping you
https://github.com/kbparagua/paloma
if you need that information to make some ajax-calls on certain urls or whatever - i always would go with solution #1. thats why data-attributes exist in HTML5

Can I use a route path for a js ajax call?

I have an ajax call that works in a .js file, using:
...
update: function(){
$.ajax({
url: '/groups/order_links',
...
but I would rather use the route path
I made the file extension .js.erb and I tried adding:
...
update: function(){
$.ajax({
url: "#{order_links_groups_path}",
...
or
...
url: "#{order_links_groups_url}",
...
but I am getting a 404 in either case - [HTTP/1.1 404 Not Found 76ms]
From a POST http://localhost:3000/groups/49
rake routes shows my routes include:
...
PUT /groups/:group_id/links/:id(.:format) links#update
DELETE /groups/:group_id/links/:id(.:format) links#destroy
order_links_groups POST /groups/order_links(.:format) groups#order_links
groups GET /groups(.:format) groups#index
POST /groups(.:format) groups#create
new_group GET /groups/new(.:format) groups#new
edit_group GET /groups/:id/edit(.:format) groups#edit
which are defined with:
resources :groups do
resources :links
collection do
post 'order_links'
end
end
groups_controller has
class GroupsController < ApplicationController
...
def order_links
params[:link].each_with_index do |id, index|
Link.where(id: id).update_all(['position = ?',index+1])
end
render :nothing => true
end
...
Rails 4.1
"#{}" is used for string interpolation in Coffeescript so I am assuming that's an error. I assume the url where this ajax request is being made from is http://localhost:3000/groups/49 because if you don't pass in a proper url then it will use the current path.
"<%= order_links_groups_path %>" would look for a variable in ruby. This would work but JavaScript files in the assets directory are being compiled without using your apps context. Meaning order_links_groups_path will be undefined.
The answer here should help: Route helpers in asset pipeline
<% url = MyRailsApp::Application.routes.url_helpers %>
url: "<%= url.order_links_groups_url %>"
Firstly, let me explain some things for you:
--
Mime Types
Rails processes mime-types at controller-level (not middleware).
This means that if you're looking to request a resource through ajax's js mime type, you'll have to define its handling in the controller, not the routes structure.
You'll be able to read more about how Rails processes the mime types here:
If the client wants HTML, we just redirect them back to the person
list. If they want JavaScript, then it is an Ajax request and we
render the JavaScript template associated with this action. Lastly, if
the client wants XML, we render the created person as XML, but with a
twist: we also include the person's company in the rendered XML, so
you get something like ...
This means that if you're looking to process a JS response, you'll be able to do the following:
#app/controllers/groups_controller.rb
class GroupsController < ApplicationController
def order_links
...
respond_to do |format|
format.js
format.html
end
end
end
This allows you to create / call the various responses you want, depending on the mime type you send through to the controller.
--
Ajax
In regards to the Ajax call, you need to be aware that you shouldn't use any dynamic linking in your asset pipeline. I know the Rails documentation recommends otherwise, but the fact is if you serve static assets (as is recommended in production), you'll lose the ability to call those routes.
Of course, as Ahmed suggested, you can rely on the coffeescript or erb preprocessing to allow you to use the route as you wish:
#app/assets/javascripts/application.js.coffee
update: function(){
$.ajax({
url: <%= order_links_groups_path %>,
...
This will route your javascript request, allowing you to process the mime type in the controller as you need.

How to make JavaScript to work when its code is rendered dynamically after performing an AJAX GET request?

I am using Ruby on Rails 3.0.9 and jQuery 1.6.2. I am trying to get JavaScript to work when its code is rendered as a partial template after performing an AJAX HTTP GET request. That is, I have the following code that performs an HTTP GET request:
# The 'articles.html.erb' file
var jqxhr = $jQ.get('http://www.my_web_site.com')
.success(function(data) {
$jQ('#data_container').replaceWith(data);
})
and this is what returns the HTTP request performed to the 'http://www.my_web_site.com' URL (note: this is a partial template within some JavaScript code):
# The 'info_articles.html.erb' file
<%= link_to 'Article link', article_path(#article), :id => 'article_link' %>
<script type="text/javascript">
$jQ('#article_link').click(function(event) {
event.preventDefault();
...
});
</script>
After the replaceWith function correctly replaces the data somewhere in the web page related to the articles.html.erb template, the Javascript just rendered (that is, that contained in the info_articles.html.erb) doesn't work. In the above example I am referring to the click event handler: it simply doesn't work as expected.
Why does this happen? How can I solve that issue?
use a jquery live binding in the main document instead.

JMVC jQuery.Model - cannot override a standard REST URL

I am using Javascript MVC models separately from JMVC (just as a jquery plugin).
Everything works fine, instead of overriding REST URLs. Look:
I am trying to override URL to retrieve data from server.
But it still tries to load data from URL "/Tags.json" instead of "/t.json".
$.Model.extend("Tag",
{
findAll: "/t.json" //overriding URL for findAll (just like in the manual)
});
$(function(){
Tag.findAll({}); //loads '/Tags.json' instead of 't.json'
})
Is it a bug?
$.Model("Tag",{
findAll : "/t.json"
},{})
You need to call $.Model not $.Model.extend
.findAll docs

Categories