Reputation: 13949
I'd like to improve the AJAX feedback in my application (after I POST a remote form in my modals, etc.).
I already have some nice feedback showing a loading animation
$(document).ajaxStart(function(){
$('.loading-feedback').show()
})
$(document).ajaxStop(function(){
$('.loading-feedback').hide()
})
But I realize it's not enough : when my AJAX requests trigger a Completed 500 Internal Server Error in 1985ms
... well nothing really happens for the user.
I would like, for example, to show an alert message on my frontend.
I already have some code that can display some flash messages I store in AJAX responses, which I'd like to reuse for this (for example, by showing oops, your AJAX request triggered a #{err_code} #{err_description}. Please tell the devs :D
I have the following code which successfully shows bootstrap flashes after AJAX requests (the content/type of the flashes being defined in my controllers)
application_controller.rb
after_filter :ajax_flash
def ajax_flash
return unless request.xhr?
if type = priority_flash
response.headers['X-Message'] = flash[type]
response.headers['X-Message-Type'] = type.to_s
flash.discard # don't want the flash to appear when you reload page
end
end
Related javascript
$(document).ajaxComplete(function(e, request, opts) {
fireFlash(request.getResponseHeader('X-Message'), request.getResponseHeader('X-Message-Type'));
# Where fireFlash is a function that displays a bootstrap alert
});
But now, If there is an error, my controller action will just return. Is it possible to detect this, and for example to fill a flash
flash[:fatal] = "oops, your AJAX request triggered a #{err_code} #{err_description}. Please tell the devs :D"
That would the be displayed on my frontend ? (note that I don't know where to find err_code and err_description)
Upvotes: 0
Views: 158
Reputation: 102055
You don't need to use Ajax to create flash messages.
Since flash messages are non-persistent and removed from the session when they are rendered you can just create new flash messages by modifying the document.
This is a minimal flash implementation:
$(document).on('flash', function(e, key, message){
var $flash = $('<li class="alert flash js-created"></li>')
.addClass("alert-" + key)
.html(message);
$(this).find('.flashes').append($flash);
});
Turbolinks will clean out the flashes for use since it replaces the entire <body>
.
You can add a global ajax failure handler by using ajaxError
instead of ajaxStop
.
var $doc = $(document);
$doc.ajaxError(function(event, jqxhr, settings, thrownError){
$doc.trigger('flash', ['error', jqxhr.status + thrownError]);
});
Upvotes: 1
Reputation: 5681
Use it this way.
$loader.fadeIn();
jqXHR = $.ajax({
url: "",
type: "POST",
data: {},
dataType: "json"
});
jqXHR.done(function( response ) {
});
jqXHR.fail(function( jqXHR, textStatus ) {
console.log( "Request failed: " + textStatus );
});
jqXHR.always(function( jqXHR, textStatus ) {
$loader.fadeOut();
});
Upvotes: 0