rails and ajax SyntaxError {stack: (...), message: "Unexpected token <"} - ruby-on-rails

I'm trying to execute a ajax every 5 seconds an get the json result. But the ajax it's not working I always get:
SyntaxError {stack: (...), message: "Unexpected token <"}
$(document).ready(function(){
setInterval(function(){
var url = "/hangout_second_user";
$.ajax({
url: url,
type: "GET",
data: {"username" : "someusername"},
dataType: 'json',
success: function(){
alert(result);
},
error: function(xhr, textStatus, error) {
console.log("Impossible to connect");
console.log(xhr.statusText);
console.log(textStatus);
console.log(error);
}
});
}, 5000);
});
Here is the action of my controller:
def hangout_second_user
#incoming_kid = Kid.where(username: params[:username]).first
prueba = REDIS.smembers "hangout:#{current_kid.id.to_s}"
if !prueba.empty?
current_kid.set_busy_status!
respond_to do |format|
format.json { render json: "{url:#{prueba[0].to_s}}", success: :ok, error: false }
end
end
end
UPDATE
I changed the render format like this:
format.json { render json: prueba[0].to_json, success: :ok, error: false }
but I still getting and html file and that's why I'm getting an error. Any help please

You should use either the $.ajax() function or the $.getJSON() function, as $.getJSON() will also perform an AJAX call.
So a possible solution would be:
setInterval(function(){
var url = "/hangout_second_user";
$.ajax({
url: url,
data: {"user_id" : "537c63ea20db9040d2000332"},
dataType: 'json',
success: function(result){
$.each(result, function(i, field){
alert(result);
});
},
error: function(xhr, textStatus, error) {
console.log("Impossible to connect");
console.log(xhr.statusText);
console.log(textStatus);
console.log(error);
}
});
}, 5000);
Or alternatively:
setInterval(function(){
var url = "/hangout_second_user";
$.getJSON(url, {"user_id" : "537c63ea20db9040d2000332"}; function(result) {
$.each(result, function(i, field){
alert(result);
});
});
}, 5000);

You cant use "#{current_kid.id.to_s}" in javascript. Try storing its value somewhere in hidden _field and access it in javascript

Related

Sending data from view to controller AJAX

how can I send the var lang to the controller so I can use it in partiel. here is my shot:
$("#search-select").on("click", function() {
var lang = $('#search-select').dropdown('get value');
$.get({
url: translations_url
data: lang,
success: function(){
console.log('data sent');
}
});
});
EDIT
current code:
$("#search-select").dropdown();
$("#search-select").on("click", function() {
var lang = $('#search-select').dropdown('get value');
$.get({
url: "#{translations_url}",
dataType: "script",
data: {
lang: lang
}
});
});
problem: params[:lang] still don't work in controller
Set correct _path to your post method:
$.ajax({
url: '<%= controller_path %>', method: 'POST',
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
data: { lang: lang },
dataType: 'json',
success: function (data) {
console.log(data);
}
});
Now you can work with lang in your controller
def method
params[:lang] # do something
answer = 'Then, you can return some data to view'
respond_to do |format|
format.json { render json: answer }
end
end
you're missing , after url: translations_url, also if you can send data as JSON with key and value, like data: {lang: 'value'}, also you don't need to specify method name if you're using GET, see the below example
$.ajax({
url: translations_url,
data: {lang: 'value'},
success: function(){
console.log('data sent');
}
});
if you need to use POST Method then include method: 'post' incase jquery ajax method doesn't call js.erb file you need to add dataType: 'script'
You can't use route path helpers on the frontend. But you can send proper URL from backend to frontend via data-attribute:
#search-select{ data: { path: translations_url } }
And then in your js:
$("#search-select").on("click", function() {
var url = $(this).data('path'),
data = { lang: $(this).dropdown('get value') };
$.get({
url: url,
data: data,
success: function(){
console.log('data sent');
}
});
});

Ruby Devise sign up with AJAX not getting json response?

I have followed this tutorial: https://blog.andrewray.me/how-to-set-up-devise-ajax-authentication-with-rails-4-0/ And am using rails 5.1.
I have implemented the json response in the controller:
class RegistrationsController < Devise::RegistrationsController
respond_to :json
end
And when I call the ajax I only get an Html/Text response:
function createUser(callback) {
$.ajax({
type: "POST",
url: window.urls.createUser,
data: {
authenticity_token: $("meta[name=csrf-token]").attr("content"),
user: grabOrderFormUserData()
},
success: function(data) {
console.log("Data: " + data);
},
error: function (data) {
//console.log("error");
}
})
}
That call works fine, but returns the HTML page of the sign up.
The url I use is createUser: hostUrl + '/users/'
What did I miss?
And no, if I add .json to my url, it will respond with 500 error code.
I think you missed to mention dataType: "json" with your ajax call , try this
function createUser(callback) {
$.ajax({
url: window.urls.createUser,
type: "POST",
data: {`enter code here`
authenticity_token: $("meta[name=csrf-token]").attr("content"),
user: grabOrderFormUserData()
},
dataType: "json",
success: function(data) {
console.log("Data: " + data);
},
error: function (data) {
//console.log("error");
}
})
}
and also in your controller try to call this block in case if you are not getting json response,
respond_to do |format|
format.json {
render json: {.....}
}
end
thank you.

Angular / Rails net::ERR_TOO_MANY_REDIRECTS on update

In my Rails app I have included a small angular app, which uses a plug-in to upload a file to Amazon S3. The code is embedded in a rails page.
After the file is successfully uploaded to S3, I wish to save the S3 key (a string) in the Rails backend using the Rails update action. I then wish to redirect to the show action on the same rails controller. The job of Angular is finished then, and there is no Angular on the show page.
So far it is all working, including the successful save of the update, and there is no error from Rails, but Angular emits the dreaded "net::ERR_TOO_MANY_REDIRECTS" error.
Note that I am not using any Angular routing, and in fact would like to avoid doing so and have Rails control page refreshes.
Rails controller code:
def update
respond_to do |format|
if #user.update(secure_params)
format.html { redirect_to #user }
format.json { head :no_content }
format.js
else
format.json { render json: #user.errors.full_messages,
status: :unprocessable_entity }
end
end
end
Angular update
$scope.upload = function (dataUrl, file) {
$scope.aws_file_key = $scope.aws.key + file.name;
Upload.upload({
url: $scope.aws.url,
method: 'POST',
data: {
key: $scope.aws_file_key,
AWSAccessKeyId: $scope.aws.access_key,
acl: $scope.aws.acl,
policy: $scope.aws.policy,
signature: $scope.aws.signature,
"Content-Type": file.type != '' ? file.type : 'application/octet-stream',
file: file
},
}).then(function (response) {
console.log('updateUser');
$timeout(function () {
updateUser();
});
}, function (response) {
console.log('response');
if (response.status > 0) $scope.errorMsg = response.status
+ ': ' + response.data;
}, function (evt) {
console.log('evt');
$scope.progress = parseInt(100.0 * evt.loaded / evt.total);
});
}
function updateUser() {
$http({
method: 'PATCH',
url: '/users/' + $scope.user.id,
dataType: 'json',
contentType: 'application/json',
data: {user: { profile_image_s3_key: $scope.aws_file_key }}
}); // $http
} // updateUser()
I did this because I wanted to use some excellent Angular file upload / resize, and this fiddle inspired me: http://jsfiddle.net/danialfarid/xxo3sk41/590/
Well I worked it out, the solution is a bit messy but avoids have a full-blown Angular app with routing, Rails API etc. I needed two things to make it work:
perform the redirection with Angular and not Rails, within the returned promise from the update
pass in headers of application/json so Rails executes the format.json respond_to instead of defaulting to format.html
headers: { 'Accept': 'application/json' }
Working code
$scope.upload = function (dataUrl, file) {
$scope.aws_file_key = $scope.aws.key + file.name;
Upload.upload({
url: $scope.aws.url,
method: 'POST',
data: {
key: $scope.aws_file_key,
AWSAccessKeyId: $scope.aws.access_key,
acl: $scope.aws.acl,
policy: $scope.aws.policy,
signature: $scope.aws.signature,
"Content-Type": file.type != '' ? file.type : 'application/octet-stream',
file: file
},
}).then(function (response) {
console.log('updateUser');
$timeout(function () {
updateUser();
});
}, function (response) {
console.log('response');
if (response.status > 0) $scope.errorMsg = response.status
+ ': ' + response.data;
}, function (evt) {
console.log('evt');
$scope.progress = parseInt(100.0 * evt.loaded / evt.total);
});
}
function updateUser() {
$http({
method: 'PATCH',
url: '/users/' + $scope.user.id,
dataType: 'json',
contentType: 'application/json',
headers: { 'Accept': 'application/json' },
data: {user: { profile_image_s3_key: $scope.aws_file_key }}
}).then(function(data){
// assumes all OK
// TODO add in error checking
$window.location.href = '/users/' + $scope.user.id;
}) // $http
} // updateUser()

Best way to return a string from a controller to ajax call

I want to create an action that returns me a single string value:
def delay_calulation()
dr = Dr.find(params[:id])
delay = dr.calc()
respond_to do |format|
format.json { render json: {"value" => delay}}
end
end
but I a "fail" in my ajax call:
$("#btn_delay").on("click", function () {
$.ajax({
type: "GET",
dataType: "script",
url: "/drs/delay_calulation/1"
})
.done(function(response){
console.log(response);
})
.fail(function(response){
console.log(response);
});
});
How can I get a single string, or something like that.
You need to pass id to the controller action while calling through Ajax. You can retrive the string by using the key name that you have mentioned in the controller.
$.ajax({
url: '/drs/delay_calulation',
data: {id: (you need to pass the id)},
type: "get",
dataType: "json",
success: function(data){
var a = data["delay"]
},
failure: function(data){
var a = data["delay"]
}
});

Read cross domain JSON response

<script>
$.ajaxSetup( {contentType: 'application/json'} );
function submit_data(f){
alert('submitting')
var data_string = $(f).serialize();
$.ajax({
url: "http://localhost:3000/application/1/contact_us.json?jsonpcallback=?"+data_string,
dataType: "jsonp",
type : 'post',
processData: false,
crossDomain: true,
contentType: "application/json",
jsonp: false,
jsonpcallback: result()
});
}
function result(){
alert('back in')
alert(data)
}
function jsonp1300279694167(){
alert('dhoom')
}
</script>
I have script above querying across domain and posting data within a form.
Everything seems to work fine. JSON response can be seen in the firebug console. I want to process the response and display status messages accordingly to the user. How should I achieve it?
UPDATE
I have tried as suggested by T.J. Crowder but have no luck yet. The modified code is as below
function submit_data(f){
alert('submitting')
var data_string = $(f).serialize();
$.ajax({
url: "http://localhost:3000/application/1/contact_us.json?"+data_string,
dataType: "jsonp",
crossDomain: true,
success: handleSuccess()
});
}
function handleSuccess(data) {
alert("Call completed successfully");
alert(data);
}
This does not accesses data and alerts undefined. If I try to pass it from success: handleSuccess() it errors and redirects with a http request.
I am getting response from a Ruby on Rails application. Here is the method I am hitting
def create
errors = ContactUsForm.validate_fields(params)
logger.info errors.inspect
if errors.blank?
respond_to do |format|
format.json {render :json => {:status => 'success'}.to_json}
end
else
respond_to do |format|
format.json {render :json => {:status => 'failure', :errors => errors}.to_json}
end
end
end
Is there any thing that I need to configure in my rails app
You're close. You just use the success callback as usual (see the ajax docs), not a special one:
$.ajax({
url: "http://localhost:3000/application/1/contact_us.json?jsonpcallback=?"+data_string,
dataType: "jsonp",
type : 'post',
processData: false,
crossDomain: true,
contentType: "application/json",
jsonp: false,
success: function(data) {
// Use data here
}
});
Also, your code:
jsonpresponse: result()
...would call the result function and then use its return value for the jsonpresponse property of the ajax call. If you want to use a separate function, that's fine, but you don't include the (), so:
$.ajax({
url: "http://localhost:3000/application/1/contact_us.json?jsonpcallback=?"+data_string,
dataType: "jsonp",
type : 'post',
processData: false,
crossDomain: true,
contentType: "application/json",
jsonp: false,
success: result
});
function result(data) {
// use `data` here
}
Also, I'm pretty sure you don't need/want the jsonp parameter if you use success, so:
$.ajax({
url: "http://localhost:3000/application/1/contact_us.json?jsonpcallback=?"+data_string,
dataType: "jsonp",
type : 'post',
processData: false,
crossDomain: true,
contentType: "application/json",
success: result
});
function result(data) {
// use `data` here
}
Finally: Are you sure you want to set contentType? That relates to the content being sent to the server, not the content being received from it. If you're really posting JSON-encoded data to the server, great, you're fine; but it looks like you're using jQuery's serialize function, which will not produce JSON (it produces a URL-encoded data string). So you probably want to remove contentType as well, both from the call and from the ajaxSetup call.
I hope if you can try jQuery-JSONP
jQuery-JSONP How To
[Example]
$.getJSON('server-url/Handler.ashx/?Callback=DocumentReadStatus',
{
userID: vuserID,
documentID: vdocumentID
},
function(result) {
if (result.readStatus == '1') {
alert("ACCEPTED");
}
else if (result.readStatus == '0') {
alert("NOT ACCEPTED");
}
else {
alert(result.readStatus);
}
});
I tried many tutorials including the answers above but had no luck. So I implemented it something like below
Form
<form action="" onsubmit="submit_data(this, '1'); return false;">
// some form fields
</form>
Submit function for form
<script>
function submit_data(f, app_id){
var data_string = $(f).serialize();
$.ajax({
url: "http://www.example.com/"+app_id+"/contact_us.js?"+data_string,
dataType: "jsonp",
crossDomain: true,
});
}
function show_errors(jsonOb)
{
$("span.error").remove();
$.each(jsonOb, function(key,val){
$("#contact_us_form_"+key).after("<span class=error>"+val+"</span>")
});
}
</script>
In my controller
def create
#application = Application.find params[:application_code]
#errors = ContactUsForm.validate_fields(params, #application)
#application.save_contact_us_form(params[:contact_us_form]) if #errors.blank?
respond_to do |format|
format.js #{render :json => {:status => 'success'}.to_json}
end
end
And finally in create.js.erb
<% if #errors.blank? %>
window.location = "<%= #application.redirect_url %>"
<% else %>
var errors = replaceAll('<%= escape_javascript(#errors.to_json)%>', """, "'")
var errors_json = eval('(' + errors + ')')
show_errors(errors_json);
function replaceAll(txt, replace, with_this) {
return txt.replace(new RegExp(replace, 'g'),with_this);
}
<% end %>
This way I called submit_form on form submit and called show_errors javascript function from server it self. And it works..
But still I would like to have comments if this is a worst solution?

Resources