Rails: Respond with js to Ajax request - javascript

I encountered some weird behaviour when using an ajax request to get a response from a rails controller action.
$.ajax({
type: 'GET',
url: '/notifications',
success: function(result) {
eval(result);
}
});
def index
respond_to do |format|
format.html { redirect_to root_url, alert: 'Page not accessible' }
format.js
end
end
So this respond_to block works fine when using requests with rails' remote: true option, but with the ajax call it just redirects the request to root_url.
When specifying json as dataType of the Ajax request. The so returns the JavaScript just fine, but because it is not valid json, eval() does not run it.
Is there a way too either start a rails remote request from within JavaScript or specify a data type with which the returned JavaScript is executable?
Even specifying dataType: 'text/javascript', in the ajax call does not do the trick.

So this respond_to block works fine when using requests with rails'
remote: true option, but with the ajax call it just redirects the
request to root_url
So the request format that is coming to the controller is HTML not JS. Using dataType: 'script' generates the request as JS and should fix your problem.
$.ajax({
type: 'GET',
dataType: 'script',
url: '/notifications'
});

Related

Rails 5: how to respond_to js after redirect?

On good old rails 4.2 I used to submit my remote: true form via ajax
$.ajax
type: 'POST'
url: post_url
data: $("##{instance_type}-modal-form").serialize() + '&redirect_url=' + redirect_url
dataType: 'script'
In my controller i was redirecting if redirect_url is present
if params[ :redirect_url ]
format.html { redirect_to params[ :redirect_url ] }
format.js { redirect_to params[ :redirect_url ] }
...
And I used to be redirected to new.js.coffee template. But now, on 5.0.0.1 it redirects to HTML
Started PATCH "/call_journals/111" for 127.0.0.1 at 2016-08-21 00:02:06 +0300
Processing by CallJournalsController#update as JS
.........
Redirected to http://localhost:3000/partners/new?call_journal_id=111
Completed 200 OK in 33ms (ActiveRecord: 3.1ms)
Started GET "/partners/new?call_journal_id=111" for 127.0.0.1 at 2016-08-21 00:02:06 +0300
Processing by PartnersController#new as HTML
Parameters: {"call_journal_id"=>"111"}
What do I do to get this fixed?
Solution
After redirect you cannot use format.js for user response. Because to use javascript response your application needs to get ajax request or remote call without redirecting page. But you can use json format.

Rails - Changing boolean in database from js.erb file

In my scenario in rails application after sharing content to facebook i will get a response object with post id
post_id: "mypostidhere"
If its not successful i will get response object with an error message.
So according to the response i want to change a boolean column of last row for the current user in my database table. And for this in my .js.erb file i tried to access current_user.model.last but it throws the following error.
undefined local variable or method `current_user' for
So how can i change the boolean column in database according to the response?
UPDATED
Ajax code
$.ajax({
type: "POST",
url: "/action"
});
Controller code
def action
current_user.modal.last.toggle!(:boolean-column-name)
end
It changes the table column successfully. But after that i am receiving an error in browser CONSOLE as below
POST http://URL/action
500 (Internal Server Error)
I am new to AJAX. What i am doing wrong in ajax request? Thanks in advance.
current_user is not a local variable to your JS function/file, it is a helper provided and available in your rails application.
So, what I will like to ask is:
How are you using current_user in the JS file?
What you can do is to make an ajax call to a controller method, and then access current_user directly from the controller.
If you want to change the db, you're going to have to communicate with your Rails app, which is done with ajax:
#app/assets/javascripts/application.js
... // your events will fire
$.ajax({
url: "/users/update",
method: "PUT",
data: { param: "value" }
success: function(data) {
// do something here
};
});
This will allow you to do the following:
#config/routes.rb
resources :users do
put :update, on: :collection
end
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def update
current_user.update(update_params)
end
private
def update_params
params.permit(:param)
end
end

.js.erb file is not executing although rendered in rails

I use rails and haml. I send data via Ajax post to a controller in rails:
$.ajax({
type: 'POST',
url: '/preview-image-upload',
processData: false,
contentType: false,
dataType : 'json',
data: data
});
Then I execute the data and render js in the controller:
respond_to do |format|
if #previewupload.save
format.js
end
The object is saved correctly. Also the .js.erb file is correctly rendered according to the server log:
Rendered path/preview_image_upload.js.erb (0.2ms)
Completed 200 OK in 603ms (Views: 8.1ms | ActiveRecord: 8.5ms)
For testing reasons, I put an alert into the preview_image_upload.js.erb file:
alert("Hello World");
but nothing happens. It looks like the .js.erb file is rendered but not executed.
Tried the solution from here:
js.erb not executing javascript but is processed rails
{ render layout: false, content_type: 'text/javascript' }
But that did not work.
The datatype to execute a Rails javascript response from a jQuery AJAX call is script
I found the solution. I simply have to remove the dataType attribute in the Ajax request. Makes it look like this:
$.ajax({
type: 'POST',
url: '/preview-image-upload',
processData: false,
contentType: false,
data: data
});

Rails render partial as widget over ajax using jsonp

I've looked at quite a few other answers on here, but I'm still struggling a bit to figure out how to set up my Rails widget.
I have this code in my widget controller:
def widget
status = Company.friendly.find(params[:id]).widget.active
body = to_json_value(render_to_string('companies/_widget', locals: { profile: self.profile }))
respond_to do |format|
format.js { render json: { status: status, html: body }, callback: params[:callback] }
end
end
private
def to_json_value(str)
str.gsub!("\"", "\\\"")
str.gsub!(/\n+/, " ")
str
end
The self.profile method just sets up a list of variables that get passed to the partial.
What I want to do is give a user a Javascript script tag that they can embed on their (external) website. When a user hits that page, the script will make an AJAX call to the widget controller and if the widget is turned on, it will receive a string of html to be rendered on the page.
So far I've got the widget controller to return a json object with the status and the html string. The problem is when I paste the localhost url into jsonlint.com, it says it is invalid. This is also confirmed when I insert a script tag into an html file and then open it in Chrome. I get an error saying there was an unexpected token :. So I then changed my controller and widget.js.erb to include a callback function. I added , callback: params[:callback] to my controller.
I also set up a callback function (doesn't do anything yet) in my widget.js.erb file. I then embed this file using a script tag in an html file and load that in Chrome. When I do, I get an error saying that showWidget is undefined.
I'm struggling to find resources that explain how to load data over jsonp from a rails app, and how callback functions come into play.
Here is my widget.js.erb:
function showWidget();
$.ajax({
type: 'GET',
url: 'http://localhost:3000/<%= params[:company] %>/widget?callback=?',
jsonpCallback: 'showWidget',
contentType: "application/json",
crossDomain: true,
dataType: 'JSONP',
success: function (data) {
var result = JSON.parse(data);
$('#company-widget').html(result.html);
},
error: function(e) {
console.log(e.message);
}
});
Here is my test.html:
<div id="company-widget"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js" type="text/javascript"></script>
<script src="http://localhost:3000/taco-corp/widget.js?callback=showWidget" type="text/javascript"></script>
I'm also not sure where this widget.js.erb script should live in my rails app. Here is what I have so far for my widget.js.erb:
I figured out what the problem was. I needed to add a callback to my rails controller and to my $.ajax method. I didn't have the callback set up correctly in my ajax call. I also needed to specify the correct header (contentType) to get around an HTTP 406 error. Here is the working jQuery code below for reference:
$(document).ready(function(){
var company = 'taco-corp';
$.ajax({
type: 'GET',
url: 'http://localhost:3000/' + company + '/widget.js?callback=?',
contentType: "application/javascript",
crossDomain: true,
dataType: 'JSONP',
success: function(data) {
$('#company-widget').html(data.html);
},
error: function(e) {
console.log(e.message);
}
});
});
And here is my rails controller:
def widget
status = Company.friendly.find(params[:id]).widget.active
body = render_to_string('companies/_widget', layout: false, locals: { profile: self.profile })
respond_to do |format|
format.js { render json: { status: status, html: body }, callback: params[:callback] }
end
end

jQuery AJAX POST to Rails 3.2.1 Params won't work

I'm trying to send an AJAX request to my rails controller (the make_suggestion method in the items controller).
I have the following javascript:
$.ajax({
url: "/items/make_suggestion", // pass to make_suggestions in recipes controller
type: "POST",
dataType: 'json',
data: parsed_data // a Javascript object/data hash
});
With debug(params) on, I'm not seeing any of the parsed_data in the params.
Can anyone please point out what is wrong? And how do I create symbols in the params in Rails through firing AJAX?
UPDATES
In my controller, I have
def make_suggestion
respond_to do |format|
format.html
format.json { render :json => params }
end
end
My ajax code:
$.ajax({
url: "http://localhost:3000/items/make_suggestion", // I'm doing the proper routing later, since '/make_suggestion' routes to 'items/1/make_suggestion'
type: "POST",
dataType: 'json',
data: parsed_data,
success: function(returned_value){
if(returned_value)
alert('true');
$('.test').append(returned_value);
},
error: function(returned_value){
$('.test').html('<p>Error in AJAX request</p>');
alert('Not working');
}
});
And my parsed_data looks like this:
Parameters: {"data1"=>{"position"=>"1", "item_id"=>"item_1",
"to_do"=>"unknown ", "selected"=>"false"}, "data2"=>{"position"=>"2",
"item_id"=>"item_2", "to_do"
=>"unknown", "selected"=>"false"}, "data3"=>{"position"=>"3", "item_id"=>"item_3 ", "to_do"=>"unknown", "selected"=>"false"},
"data4"=>{"position"=>"4", "item_id "=>"item_4", "to_do"=>"unknown",
"selected"=>"false"}, "data5"=>{"position"=>"5" , "item_id"=>"item_5",
"to_do"=>"unknown", "selected"=>"false"}}
But when I went to /items/make_suggestion.json, it's only showing the following:
{"action":"make_suggestion","controller":"recipes","format":"json"}
You can view / trace parameters in multiple ways
1) tail your rails log file tail -f log/development.log, note that the rails web server usually starts tailing to the console once started
2) raise exceptions and view debug output in the browser
3) use the javascript console in your browser (some are built-in), also consider Firefox with Firebug plug (use the 'console') tab
Tailing the rails log
every single request made to your rails server will show all of the parameters passed, as well as the controller and action which received the request and all sql statements generated
consider adding the 'awesome_print' gem to your application for better logging output, once installed logger.ap params will give you a nice readable output
Raise exceptions
not needed very often but if you add raise "ZOMG" as the first line of your controller action, it will render html output and show all the parameters passed. This is almost useless for ajax calls
Javascript Console
This will show all ajax requests and all parameters that javascript is sending to the rails server and all data being returned as well, very useful
Rails will map the javascript ajax parameters to a ruby hash, this is very nice as these data structures are almost exactly the same in the browser as they are in rails, i.e.
// javascript data structure
var parsed_data = {
foo: "FOO",
bar: "BAR",
person: {
first_name: "Joe",
last_name: "Smith"
}
}
output to the log using awesome_print would result in a ruby hash something along the lines of
logger.ap params
{
:foo => "FOO",
:bar => "BAR",
:person => {
:first_name => "Joe",
:last_name => "Smith"
}
}
# access the data
params[:foo]
# => "FOO"
params[:person][:first_name]
# => "Joe"
Your data post to controller not detail.
look my example :
$.ajax({
url:'/contact/new',
type:'get',
data:{object_param:{
first_name:'zainulmasadi',
last_name:'masadi ganteng',
phone_number:'089745674119541'}},
dataType:'json',
success:function(returned_value){
if(returned_value)
alert('true');
}
})
and my controller
def new
#contact = ContactPhone.create(params[:object_param])
if #contact.save
respond_to do |format|
format.html
format.json {render :json => #contact}
end
end
end

Categories

Resources