Show Rails error message in Ajax alert - javascript

Using Rails 3.2. I wonder how can we push the error from Rails to show in the Ajax alert. Here is my code:
# posts_controller.rb
def update
#post = Post.find(params[:id])
if #post.update_attributes(params[:name] => params[:value])
render :nothing => true
else
render :text => #post.errors.full_messages[0], :status => :unprocessable_entity
end
end
# _form.html.erb
$("#status_buttons button").click(function() {
$.ajax({
type: 'POST',
url: "<%= post_path(#trip) %>",
data: { _method: 'PUT', name: this.name, value: this.value },
error: function() {
alert(" *****************Rails error message here**********************");
}
});
});
The conventional validation error message should appear in the alert(). Any idea?
Thanks.

one way to determine is to pass at least 3 arguments to the callback function and checking the console (or an alert) for whatever argument passes the error.
error: function(a,b,c) {
alert('a contains ' + a);
alert('b contains ' + b);
alert('c contains ' + c);
}
one of them should contain the error message :) Good luck!

error: function( jqXHR, textStatus, errorThrown ) { ...

Related

sweetalert ajax functionality

i am trying to use sweetAlert2 for my ajax, creating a form inside and then do its process and get the results back, but i am stuck at one point which is when i send the results how do i process the ajax inside it,
Here is my code as of now
Swal.fire({
title: 'Request PlayForm',
html: `<textarea name="da" id="da"></textarea>`,
confirmButtonText: 'Submit',
focusConfirm: false,
preConfirm: () => {
const textData = Swal.getPopup().querySelector('#da').value
if (da== '') {
Swal.showValidationMessage(`Please enter details.`)
}
return { da: da}
}
}).then((result) => {
Swal.fire(`
Email Sent Successfully -- this message should come when i get a success from my ajax else it will display error which i can get from ajax
`.trim())
})
You can do it like this.
Swal.fire({
title: 'Request PlayForm',
html: `<textarea name="da" id="da"></textarea>`,
confirmButtonText: 'Submit',
focusConfirm: false,
preConfirm: () => {
const textData = Swal.getPopup().querySelector('#da').value;
if(!textData || !textData.trim()) {
Swal.showValidationMessage(`Please enter details.`)
}
return textData;
}
}).then((result) => {
var myResult = result.value;
console.log("calling ajax");
$.ajax({
url: 'https://pokeapi.co/api/v2/pokemon/' + myResult,
//data: {'da':myResult}, <== use this if you're sending any data
type: 'get', // or post, depending what you do in the background,
// dataType: 'json' - data type of your response. It's optional,
// you can set it to something else, like text, or application/pdf,
//or something else
beforeSend: function() {
console.log("this is before send - we want to get some info " + myResult);
// disable buttons to prevent double clicks,
// or do something else
},
success: function(data) {
// Process the response - data
// Send mail if successful
if(data) {
Swal.fire(`
Email Sent Successfully -- this message should come
when i get a success from my ajax else it will display
error which i can get from ajax
`.trim());
console.log(data);
} else {
Swal.fire(`There was an error: ` /* your error here*/);
}
},
error: function(desc, err) {
Swal.fire(`
AJAX error! Description: ` + JSON.stringify(desc) + `,
error: ` + JSON.stringify(err));
}
});
// END AJAX
});
// END .then(...)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/sweetalert2#11"></script>
The variable myResult (you can name it whatever you like) stores the result of da / return of your preconfirm. You could process it later on, to see if it matches what you expect (for example, whether there were any illegal characters, or if you were expecting a number, or a certain format, but the user decided to be cheeky and type in something else, etc).
If the input was alright, you move on to the else part in the .then(...), and call your AJAX there. Read the comments in the code for more info.

Defining routes in AJAX and Rails

Error I get: undefined variable article_id.
What I am trying to achieve : Define the correct route in AJAX and Rails.
What I need: The structure articles/1/comments/2.
Goal: Note that my goal is to only load comment using AJAX, not article.
In the AJAX script below what I currently have undefined is article_id, for which I wrote the following:
var getArticle = function () {
return $('.article-title').each(function() {
var article_id = $(this).data('article-id');
});
};
$(document).ready(getArticle);
AJAX:
var loadComment = function() {
return $('.comment-content').each(function() {
var comment_id = $(this).data('comment-id');
return $.ajax({
url: "/articles/" + article_id + "/comments/" + comment_id,
type: 'GET',
dataType: 'script',
error: function(jqXHR, textStatus, errorThrown) {
return console.log("AJAX Error: " + textStatus);
},
success: function(data, textStatus, jqXHR) {
return console.log("Worked OK!");
}
});
});
};
$(document).ready(loadComment);
$(document).on('page:change', loadComment);
Index:
- #articles.each do |article|
%article-title{ :class => "article-title", "data-article-id" => article.id }= article.title
- article.comments.each do |comment|
%comment-content{ :id => "comment-#{comment.id}" }
Add this to your routes.rb
resources :articles do
resources :comments
end
And add the following controller:
class CommentsController < ApplicationController
def show
#article = Article.find(params[:article_id])
#comment = #article.comments.find(params[:id])
render json: #comment
end
end
Running something like:
curl http://localhost:3000/articles/123/comments/456.json
will set the params[:article_id] to 123 and the params[:id] to 456, the id is intended to be used as a comment id.

handle Status Code:200 OK on ajax save form

I have the following HAML form:
.row
.col-lg-6
.panel.panel-default
.panel-heading
%h1.box-title
%i.fa.fa-calendar.fa-fw
Availability
.panel-body
= form_tag dashboard_kid_availabilities_url(current_kid), :method => 'post', id: "save-availability", remote: true do
.form-group
= _("Date")
= select_date(Time.now + 1.day, order: [:day, :month, :year])
%br
= _("Hour")
= select_hour(Time.now )
.form-group
= submit_tag _('Save'), class: 'btn btn-blabloo btn-xs'
With the following ajax request:
:javascript
$("#save-availability").submit(function () {
var availability_day = $("#date_day").val();
var availability_month = $("#date_month").val();
var availability_year = $("#date_year").val();
var availability_hour = $("#date_hour").val();
var calendar = $("#calendar").fullCalendar();
$.ajax({
url: $(this).attr('action'),
type: "POST",
data: {"date_day" : availability_day, "date_month" : availability_month, "date_year" : availability_year, "date_hour" : availability_hour},
success: function(result){
alert("salvada disponibilidad");
},
error: function(xhr, textStatus, error) {
console.log("Impossible to connect");
console.log(xhr.statusText);
console.log(textStatus);
console.log(error);
}
});
});
And this is the code of my controller:
def create
#availability = Availability.new()
#availability.availability_date = (params[:date][:day] + "/" + params[:date][:month] + "/" + params[:date][:year] + " "+ params[:date][:hour]).to_str
#availability.end_availability_date = (params[:date][:day] + "/" + params[:date][:month] + "/" + params[:date][:year] + " "+ (params[:date][:hour].to_i + 1).to_s).to_str
#availability.kid = current_kid
if #availability.save
flash[:notice] = 'Availability created successfully'
respond_to do |format|
format.json { render json: #availability.to_json, success: :ok, error: false }
end
else
flash[:error] = 'Availability not created'
end
end
Everything work great (the record is saved), but the success code on my javascript code it's never execute, instead the error code it's executed.
I'm getting this error on my console:
POST http:// localhost:3000/dashboard/kids/jean_oso/availabilities 500
(Internal Server Error) application.js?body=1:8707send
application.js?body=1:8707jQuery.extend.ajax
application.js?body=1:8137(anonymous function)
edit:1808jQuery.event.dispatch
application.js?body=1:5096elemData.handle application.js?body=1:4767
Impossible to connect edit:1816 Internal Server Error edit:1817 error
edit:1818 Internal Server Error
What I'm doing wrong.
Thanks in advance

Use ajax to post back to same page

I would like to post the result of an ajax request back to the same page that it was requested from. Here are the interacting parts:
AJAX in Jquery
var ids = 1
$(document).ready(function(){
$('#showbtn').on('click', function() {
$.ajax({
url: "http://localhost:3000/teamplayers.json",
data: {'resolution':ids},
type:"post",
dataType: "json",
cache: true,
success:function(){
$('#test3').val(1);
alert("test 3");
},
error: function(error) {
alert("Failed " + console.log(error) + " " + error)
}
});
});
});
This is supposed to set a variable here:
Teamplayer Controller
# GET /teamplayers
# GET /teamplayers.json
def index
#teamplayers = Teamplayer.all
#fteams = Fteam.all
#teamplayer2 = 1
tid = params[:resolution] <-It should set here per the data section above
#ids = tid
end
unfortunately it calls this section of the same controller
# POST /teamplayers
# POST /teamplayers.json
def create
#teamplayer = Teamplayer.new(teamplayer_params)
respond_to do |format|
if #teamplayer.save
format.html { redirect_to #teamplayer, notice: 'Teamplayer was successfully created.' }
format.json { render action: 'show', status: :created, location: #teamplayer }
else
format.html { render action: 'new' }
format.json { render json: #teamplayer.errors, status: :unprocessable_entity }
end
end
end
So what do I do to make it post to the same page.
You are POSTing the ajax, which means the create action will be hit, not the index action. You should be able to see this in your server log output when you hit the page.
If you want to hit the index action, you need to do an GET ajax request with the resolution data set so you can get the data you want.
Additionally, you probably maybe don't want to cache this ajax request if it is actually dynamic data, but it is up to you.
Edit from comments:
You need to add your parameter as a query string for a GET, not as generic "data".
Try something like this:
$.ajax({
url: "http://localhost:3000/teamplayers.json?resolution="+ids,
type:"GET",
dataType: "json",
success:function(){
$('#test3').val(1);
alert("test 3");
},
error: function(error) {
alert("Failed " + console.log(error) + " " + error)
}
});
});
Another edit from comments:
# GET /teamplayers
# GET /teamplayers.json
def index
#teamplayers = Teamplayer.all
#fteams = Fteam.all
#teamplayer2 = 1
tid = params.fetch(:resolution) { 0 } # make sure we got something
#ids = tid.to_i # coerce string param to integer
end

Rails render partial Ajax Error BUT correct response shown in Debugger

I'm trying to trigger an additionnal ajax query on an existing link using unobstrusive Javascript.
The Query is going to the server and processed, returning for the test the string "javascript template ok".
But, the ajax "success" function is never called. In place, it is the "error" function that is triggered...
I looked in the Chrome Debugger and I can see the response text coming back from the server, but never is the "success" method called... :-(
My call is
jQuery.ajax({
type: 'POST',
success: function(response) {
$("#details").html(response);
console.log(response);
},
error: function(){
alert("Error\nData could not be retrieve from the server");
},
url: '/treeview/show/1538.js',
cache: false,
});
(url is harcoded in this example). The same Url in the browser gets the correct data with no layout :-)
Removing the ".js" in the url returns the html template with layout and the update of the "details" div is achieved correctly...
The controller is
respond_to do |format|
format.html # show.html.erb
format.js { render :inline => "JAVASCRIPT TEMPLATE !" }
end
Thank you
EDIT :
Here is the object returned from the ajax query (first argument of error: function(jqXHR) ):
Object
abort: function ( statusText ) {
always: function () {
complete: function () {
done: function () {
error: function () {
fail: function () {
getAllResponseHeaders: function () {
getResponseHeader: function ( key ) {
overrideMimeType: function ( type ) {
pipe: function ( /* fnDone, fnFail, fnProgress */ ) {
progress: function () {
promise: function ( obj ) {
readyState: 4
responseText: "JAVASCRIPT TEMPLATE !"
setRequestHeader: function ( name, value ) {
state: function () {
status: 200
statusCode: function ( map ) {
statusText: "OK"
success: function () {
then: function ( /* fnDone, fnFail, fnProgress */ ) {
__proto__: Object
So I get the correct response text ??!! Where can be the error then ? :-s
You do not explicitly specify the dataType option for jQuery.ajax so jQuery infers it to be script (relying on MIME type served by Rails). Since JAVASCRIPT TEMPLATE ! is not a valid Javascript statement, parser error is thrown. There are two options to get success callback called instead of error:
Explicitly specify dataType as text:
jQuery.ajax({
type: 'POST',
dataType: 'text',
// ...
});
Or return valid Javascript from controller:
respond_to do |format|
format.html # show.html.erb
format.js { render :inline => "{}" }
end
Have you considered that the response might get evaluated as javascript code and therefore throwing an error which gets caught?
Okay, I am not sure about this one, but maybe one of this helps:
Use done() and fail() instead of error/success. Like this:
$.ajax({ ...}).done(...).fail(...);
or
Try using the correct function arguments in the success/error callbacks. Maybe jQuery doesn't like the signature and thus does not call the function?
to your ajax call, add
dataType: 'json',
and, controller
format.js render :text => { :some_data => "JAVASCRIPT TEMPLATE !" }.to_json
Edit your error call to pass the error data to the DOM:
error: function(data){ console.log(data); }
Then you will see exactly what is happening.
This is what you should do:
$.post('/treeview/show/1538.js', function(response, data){
$("#details").html(data.responseText);
}).error(function(){
alert("Error\nData could not be retrieve from the server");
})
Optional in your controller
respond_to do |format|
format.html # show.html.erb
format.js { render text: "JAVASCRIPT TEMPLATE !" }
end
Try it.

Categories