I was hoping someone could help me out on this one, and a possible explanation. I have a rails controller called get_songs that will get a hash of songs from the currently logged in user. That said, whenever a particular button is clicked I want to get the data from the get_songs controller at put it in javascript variable. The following is what I have so far.
playlist.js.erb
function get_songs() {
var mysongs;
$.ajax({
type : 'GET',
url : "getSongs",
dataType : 'json',
success : function(response) {
}
});
}
My controlller
class StaticPagesController < ApplicationController
respond_to :js, :json, :html
def get_songs()
if user_signed_in?
session[:user_id] = current_user.id
present_user = User.find(session[:user_id])
present_user = present_user.playlist.keys
#songs = present_user
respond_to do |format|
format.json { render :json => #songs}
end
end
My routes:
match '/getSongs', to: 'static_pages#get_songs', via: 'get'
If everything was working you would do:
success : function(response) {
mysongs = response;
}
The 'response' parameter on the success function is the result of the ajax call you are sending from your controller; the #songs json.
A simple way to debug your javascript (to check what is the value of your 'response' after the ajax request) is to right-click on your browser and click on 'inspect', then go to the 'Sources' tab, look for your javascript file and click the line where you want to add the debug point (in this case the line with 'mysongs = response', then refresh the page. It should stop running at that point and show the value of 'response'.
I think problem in session. When you send request using ajax, you don't send any cookies and session. So try this
$.ajax({
type:"GET",
beforeSend: function (request){
//your token is here
request.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr("content"));
},
url: "getSongs",
dataType : 'json',
success : function(response) {
console.log(response)
}
});
Also, make sure that you have <%= csrf_meta_tag %> in layouts/application.html.erb
UPD
If you are using gem 'jquery-rails'
and have //= require jquery_ujs in application.js file
Content of csrf_meta_tag automatically will be added to all your ajax requests
Related
I'm trying to auto-refresh a single partial view every 60 seconds on the index page. I tried splitting the actions into two routes, so that the JS would be easier to change and manage. It seems to be a problem with the respond_to block, maybe you can help me with a better approach.
feed_controller.rb
def index
#hashtags = hashtag_refresh
end
def hashtag_refresh
Hashtag.order('created_at DESC').limit(10).uniq
respond_to do |format|
format.js
end
end
feed\hashtag_refresh.js.erb
$('.trends_li_container').html("<%= escape_javascript(render('feed/shared/hashtag_list')).html_safe %>");
routes.rb
get 'feed/hashtag_refresh', to: 'feed#hashtag_refresh'
hashtag_autorefresh.js
//Refresh Hashtags Partial
$(document).ready(function (){
setTimeout(refreshHashtag, 60000)
});
//Calls action refreshing the partial
function refreshHashtag() {
$.ajax({
url: 'feed/hashtag_refresh',
type: 'GET',
dataType: 'script'
})
}
feed/shared/ folder
_hashtag_list.html.erb
feed/ controller folder
hashtag_refresh.js.erb
Server Development Log
Started GET "/feed/hashtag_refresh?_=1462210930323" for 127.0.0.1 at 2016-05-02 13:45:05 -0400
Processing by FeedController#hashtag_refresh as JS
Parameters: {"_"=>"1462210930323"}
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 5]]
Rendered feed/shared/_hashtag_list.html.erb (0.0ms)
Rendered feed/hashtag_refresh.js.erb (11.5ms)
Completed 200 OK in 50ms (Views: 47.5ms | ActiveRecord: 0.0ms)
try changing your function refreshHashtag() to this
//Calls action refreshing the partial
function refreshHashtag() {
$.ajax({
url: 'feed/hashtag_refresh'
type: 'GET', //POST
dataType: 'script'
})
}
I think the problem is the returning value of hashtag_refresh. You expect it to return a collection of Hashtags, but actually it returns the return value of respond_to, which I don't know what it really is :P
Try modifying your controller like this:
def index
hashtag_refresh do |hashtags|
#hashtags = hashtags
end
end
def hashtag_refresh
yield Hashtag.order('created_at DESC').limit(10).uniq
respond_to do |format|
format.js
end
end
And your javascript
// Refresh Hashtags Partial
$(document).ready(function (){
setInterval(refreshHashtag, 60000)
});
// Calls action refreshing the partial
function refreshHashtag() {
$.ajax({
url: 'feed/hashtag_refresh.js',
dataType: 'javascript'
})
}
By the way, calling setTimeout recursively is preferred over setInterval because setInterval requires manual cancel, and if you forget to cancel, it will run forever. So your javascript can be like this:
//Refresh Hashtags Partial
$(document).ready(function (){
(function refreshHashtag() {
$.ajax({
url: 'feed/hashtag_refresh.js',
dataType: 'javascript'
}).then(function() {
setTimeout(refreshHashtag, 60000);
});
})();
});
Hope it will resolve your problem :)
UPDATE
If you got the error ActionController::UnknownFormat, then it simply means that rails don't recognize the format js or the mime type text/javascript. We can teach rails by adding some config in config/initializers/mime_types.rb
config/initializers/mime_types.rb
# The RFC standard mime type for javascript
Mime::Type.register "application/javascript", :js
# The legacy but widely used mime types for javascript
Mime::Type.register "text/javascript", :js
Mime::Type.register "application/x-javascript", :js
I have an instance variable, #source_code in my Rails controller that I want to retrieve in my Ajax response via the success function. I am calling this Ajax function from my index.html.erb file and it renders a show.html.erb file. I want to get my text area to print out the #source_code.code value.
SourcesController.rb
def show
Rails.logger.debug("REACHED: show >>")
#source_code = Source.find_by(id: params[:id])
Rails.logger.debug("REACHED: source_code >>" + #source_code.code.to_s)
#sources = Source.all
end
index.html.erb
function updateTextArea(source_id){
console.log(source_id);
$.ajax({
type: "GET",
url: "/sources/" + source_id,
data: {source_id: source_id},
success: function (response){
alert("Ajax success")
console.log("<%= #source_code %>");
editor.session.setValue("<%= #source_code %>");
},
error: function(){
alert("Ajax error!")
}
});
Expanding on Nycen's answer, you first want your controller handle the ajax request and return a JSON response:
def show
respond_to do |format|
format.json { render json: Source.find_by(id: params[:id]) }
end
end
PS: Take care with that, it will send all of the fields of your Source record down the wire. I call slice (see ActiveRecord.slice()) on the model to limit the fields returned in the JSON.
Then your JavaSript needs to use the JSON result of that ajax call:
function updateTextArea(source_id){
console.log(source_id);
$.ajax({
type: "GET",
url: "/sources/" + source_id,
success: function (response){
alert("Ajax success")
console.log(response.code);
editor.session.setValue(response.code);
},
error: function(){
alert("Ajax error!")
}
});
It depends on how your routes are setup, but there should be no need to set the data property in the Ajax call. Your route is likely to pull it from the URL path: /sources/12345.
Note there is no show.html.erb with this setup. There is no view, your controller just returns JSON.
You're expecting your success handler to have access to #source_code just like a "show.html.erb" view would, but it doesn't work that way.
When you use ajax, the method is called from the browser; it's a piece of code you send away from your server, it can still interact with it, but it doesn't have access to the controller variables.
So, your show action needs to render something your handler can understand, for instance json. Then you'll have access to it in your success by reading your "response" variable.
I have a page with a list of user sites and on it I am making an API call to check the status of something for each site. The problem is that it makes the page take forever to load, so I would like the page to load and then that table element to update after it's done checking using AJAX or jQuery. I'm not great with AJAX or jQuery though and all the Rails/Ajax tutorials I've been reading seem to deal more with forms and data stored within the database. Here's my table element:
Part of My View
<td>
<% if HTTParty.get(site.domain + 'api')["status"] == "ok" %>
OK
<% else %>
Error
<% end %>
</td>
The Controller Action Loading View
def sites_page
#sites = Site.where(user_id: current_user.id)
render 'sites_page'
end
How can I make this load separately as mentioned above? I know I don't have any attempted code yet, but I really don't know where to start.
Thanks for your help.
Just attach AJAX call to the td on window load, it will be evaluated later after page is rendered. AJAX call can be something like this:
$(window).load(function() {
var target = $(".td-that-will-be-evauated-later")
url = target.data("url")
$.ajax({
url: url,
type: "GET",
dataType: "json",
success: function(result){
target.html(result.body)
},
error: function(xhr, status, error) {
$(target).html("error");
}
})
})
Url should point to the controller action that will fetch information for particular user, for example:
class UsersController < ActionController::Base
def fetch_info
#user = User.find(params[:id])
#response = #user.fetch_info
render json: {success: true, body: response.body}
end
end
This is my ajax handling code:
$.ajax({
url: "shirts/first?page=" + params[:page],
type: "GET"
})
How to tell Ajax to take the results from the next page in the shirts/first file?
I wrote the code as I've shown but it throws a error saying 'syntax error'! How can I solve this?
Also my .js.erb file if its of some help:
$("#container1").append("<%= escape_javascript(render 'shirts/first')%>");
If you're performing ajax pagination, you'll have to ensure you can handle the Ajax request on the controller (using respond_to), and send the correct data:
JS
#app/assets/javascripts/application.js
$("a.pages").on("click", function() {
$.ajax({
url: "shirts/first?page=" + $(this).attr("id"),
type: "GET"
});
});
You'd need to have your pagination buttons with the page's ID for this
Controller
#app/controllers/shirts_controller.rb
def first
#shirts = Shirt.where(your_query)
respond_to do |format|
format.html
format.js
end
end
View
#app/views/shirts/first.js.erb
$("#container1").append("<%= raw(escape_javascript(render 'shirts/first')) %>");
you have mixed the rails params and javascript code, in javascript
url: "shirts/first?page=" + params[:page]
has syntax error because of : charachter, and even if you remove it means you have a javascript object named params and page is a variable which refers to a key in the params object, whereas here params[:page] refers to a querystring which its key is page in the current request from the client.
So change it like:
$.ajax({
url: "shirts/first?page=<%= params[:page] %>",
type: "GET"
});
You have to be careful here, cause the code above means the current page is being loaded with the page in its querystrings like: http://example.com/homepage?page=helloworld and helloworld probably is the other page in your story.
and for your .js.erb file, in rails 3.0.8, you have to wrap every escape_javascript call with raw():
$("#container1").append("<%= raw(escape_javascript(render 'shirts/first')) %>");
I've been googling all day and still couldn't find any answers.So basically in my javascript function, I want to send a GET request to my rails controller and the rails controller will send back a JSON object. Any idea how do I do this? thnx
Using jQuery I would do something like this:
In the selector and event you want, for instance on clicking some element:
$(function() {
$('#foo').click( function(){
var params = '{"field1": "value1", "field2: "value2"}';
$.get('/controller/bar', params, function(data){
alert(data);
});
});
});
Then in your Rails controller:
def bar
/// hack hack hack
render :json => {"response" => "OK"}
end
The in your routes.rb:
match 'controller/bar' => 'controller#bar'
Finally, change "controller" according to your code. Firebug is your friend!
you can use jQuery ajax to make get or post request from javascript.
jQuery.ajax({
url: "url to controller method", // it should be mapped in routes.rb in rails
type: "GET",
data: {field1 :value1, field2:value2}, // if you want to send some data.
dataType: "json"
success: function(data){
// data will be the response object(json)
}
});
response from rails will something similar to the below, you can modify as per your requirement.
respond_to do |format|
format.js { render :json => #json_data }
end