Error part in jQuery is missing - javascript

I build following JavaScript part and everything works fine. But I'm not sure if the code is completely right. Because in my script I only use success: function() but I don't use error. Is it a MUST to have error in a jQuery AJAX call?
Currently I'm catching the errors in my php controller function and echo them in the success part.
$(document)
.ready(function() {
var groupName = '';
var groupid = '';
$(".grp")
.click(function() {
$('.text-danger')
.html('');
groupName = $(this)
.data('groupname');
groupid = $(this)
.attr('id');
$('.text')
.html(groupName);
$('#dataModal')
.modal({
show: true
});
});
jQuery(".grpval")
.click(function(e) {
e.preventDefault();
jQuery.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]')
.attr('content')
}
, });
jQuery.ajax({
url: "{{ route('request_group') }}"
, method: 'post'
, data: {
'Gruppe': groupid
}
, success: function(data) {
if (typeof data.successsuccess != 'undefined') {
jQuery('.alert-success')
.show();
jQuery('.alert-success')
.html('<p>' + data.successsuccess + '</p>');
$('#dataModal')
.modal('toggle');
window.scrollTo(500, 0);
} else if (typeof data.successdberror != 'undefined') {
jQuery('.alert-danger')
.show();
jQuery('.alert-danger')
.html('<p>' + data.successdberror + '</p>');
$('#dataModal')
.modal('toggle');
window.scrollTo(500, 0);
} else {
jQuery.each(data.errors, function(key, value) {
jQuery('.alert-danger')
.show();
jQuery('.alert-danger')
.html('<p>' + value + '</p>');
$('#dataModal')
.modal('toggle');
window.scrollTo(500, 0);
});
}
}
});
});
});
EDIT: Here is the function from my Controller:
public function setGroupRequest(Request $request){
$validator = \Validator::make($request->all(), [
'Gruppe' => [new ValidRequest]
]);
$groupid = $request->input('Gruppe');
if ($validator->fails())
{
return response()->json(['errors'=>$validator->errors()->all()]);
}
try{
$groups_request = new GroupRequest();
$groups_request->idgroups = $groupid;
$groups_request->iduser = Auth::id();
$groups_request->request_active = 1;
$groups_request->save();
$db_status = 'success';
}catch(\Exception $e){
$db_status = 'error';
}
if($db_status == 'success'){
return response()->json(['successsuccess'=>'Record is successfully added']);
}else{
return response()->json(['successdberror'=>'DB Error! Values could not be saved.']);
}
}

Error handling is required as you never know different things on the internet might result in failure of request for example,
Network failure.
Lost database connection
Unauthorised access/access denied
Any variable being not defined
There is nothing wrong in your way of writing PHP error in success, but writing it in $ajax error callback function is preferred as it helps in separating error & success logic.
In fact you can add a jquery error callback function as well to your $ajax which will handle all the errors originating from above mentioned internet failures.
You can add error function, which will receive any type of error coming from backend.
jQuery.ajax({
url: "{{ route('request_group') }}",
method: 'data: {
'Gruppe': groupid
},
success: function(data) {
//code here
},
error: function (jqXHR, exception) {
//error handling
}
})
In your PHP file,
if ($query) {
echo "success"; //whatever you want to show on success.
} else {
die(header("HTTP/1.0 404 Not Found")); //Throw an error on failure
}
This way you can catch PHP error as well as any internet Network errors in your jquery ajax.

Related

jQuery AJAX post returns 403 error

I have the following script for AJAX to do login, but with some passwords that contain characters like "!##" it will return 403 error and will not submit to the PHP.
$(document).ready(function () { // When the document is ready
$('#login').click(function (e) { // We attach the event onchange to the select element
e.preventDefault();
var form_info = "";
$('#login_form *').filter(':input').each(function(){
if(this.value !== ""){
form_info += this.name;
form_info += "=";
form_info += encodeURIComponent(this.value);
form_info += "&";
}
});
form_info += "function_name=login";
var form = $('#login_form').serialize() + "&function_name=login";
$.ajax({
url: "function_ajax.php", // path to you php file
type: "post", // We want a POST request
dataType: 'html',
data: form_info,
statusCode:
{
404: function () {
alert('Could not contact server.');
},
500: function () {
alert('A server-side error has occurred.');
}
},
error: function ()
{
alert('A problem has occurred.');
},
beforeSend: function ()
{
alert(form_info);
alert(form);
},
complete: function ()
{
},
success: function (data) { // The function to execute if the request is a -success-,
if(data === "1"){
if (document.referrer !== "") {
window.location.href = document.referrer;
}
else{
window.location.href = "some_domain"
}
}
else if (data === "2")
{
alert("invalid");
}
else {
alert("empty");
}
}
});
});
});
You will find that I'm trying both ways to encode each element and the serialize just to check if I'm getting the same result, and I'm getting the same result, but still, it's getting this error.
If I try to encode the whole serialize, then I will not get the error but in PHP, the $_POST array will have the first key as the data I'm sending with no value.
encodeURIComponent($('#login_form').serialize()) + "function_name=login"
then the $_POST will be like
array(
[email=email#gmail.com&password=pass123!##&function_name=login]=>
)
which will not be useful for me.

CakePHP AJAX-Call: An error occured: undefined

I am trying to get some sample ajax app running with cakephp. I started off reading this blogpost: http://www.dereuromark.de/2014/01/09/ajax-and-cakephp/ which I tried to adapt do my architecture.
Now I am stuck here:
When I change the selection of the first select-box, I get an error-alert: undefined.
When I trie to call the AJAX-URL directly in the browser, it actually returns the correct html-content that is supposed to be updated in the second select-box but I see there is an 500 Server-Error also being returned which sais it cannot load the recource http://localhost/favicon.ico. Is that the problem why the ajax-call sais "an error occured"? I don't know why this resource is even called and why it is looking in localhost/ and not the app-folder. Can anybody tell me what I need to do to get the ajax-sample running? This is the JS-Code for the ajax-call:
<script>
$(function() {
$('#countries').change(function() {
var selectedValue = $(this).val();
var targeturl = $(this).attr('rel') + '?id=' + selectedValue;
$.ajax({
type: 'get',
url: targeturl,
beforeSend: function(xhr) {
alert(targeturl);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
},
success: function(response) {
alert(response);
if (response.content) {
alert("content");
$('#provinces').html(response.content);
}
},
error: function(e) {
alert("An error occurred: " + e.responseText.message);
console.log(e);
}
});
});
});
</script>
These are my controller-functions:
public $components = array('Session','RequestHandler');
...
public function chained_dropdowns() {
$countries = $this->TestRun->find('list');
$countryProvinces = array();
foreach ($countries as $key => $value) {
$countryProvinces = $this->TestRun->TestStepRun->find('list',array('conditions'=>array('TestStepRun.test_run_id'=>$key)));
break;
}
$this->set(compact('countries', 'countryProvinces'));
}
public function country_provinces_ajax() {
//$this->request->onlyAllow('ajax');
$id = $this->request->query('id');
if (!$id) {
throw new NotFoundException();
}
//$this->viewClass = 'Tools.Ajax';
//$this->loadModel('Data.TestStepRun');
$countryProvinces = $this->TestRun->TestStepRun->find('list',array('conditions'=>array('TestStepRun.test_run_id'=>$id)));
$this->set(compact('countryProvinces'));
}
}
And I added in my routes.php:
Router::parseExtensions();
Router::setExtensions(array('json'));
[Update]
I just changed the error-output-line to:
alert("An error occurred: " + e.responseText);
Now, I get as error-message: "An error occured: <option value="">..."
This is the data from the json-view, which should be passed to the success-function. I just don't know, why it throws an error.
could it be, that it's rather a problem with your jQuery-request configuration?
Maybe try to add
dataType:"html",
in your $.ajax configuration.
to solve the issue. Normally CakePHP just outputs what you enter into your .ctp - file.
If you don't define json there, you will not get any object (regardless of what the console sais).

How to add data parameter in ajaxSend properly?

In some circumstance I need to add POST parameter programmatically to AJAX request.
I'm trying something like this:
$(document).ajaxSend(function(event, jqXHR, ajaxOptions) {
ajaxOptions.data = "additional_key=additional_value&" + ajaxOptions.data;
ajaxOptions.context.data = "additional_key=additional_value&" + ajaxOptions.context.data;
console.log(ajaxOptions, 'ajaxOptions');
});
But additional_key isn't appear in $_POST array.
You can use ajaxPrefilter for this :
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
if (originalOptions.type !== 'POST' || options.type !== 'POST') {
return;
}
options.data = $.extend(originalOptions.data, { yourdata : yourvalue });
});
See http://api.jquery.com/jquery.ajaxprefilter/ for more infos.
testing your above code gave me an error that ajaxOptions.context was undefined.
First, I'd advise that you check for existence first: (Assuming that context is ever going to be defined)
if(ajaxOptions.context) {
ajaxOptions.context.data = "additional_key=additional_value&" + ajaxOptions.context.data;
} else {
ajaxOptions.data = "additional_key=additional_value&" + ajaxOptions.data;
}
Sending off a mock AJAX request showed me that the data is being passed through when inspected in Firebug.
I tested the code by removing the context line, and it seemed to work:
Code:
$(document).ajaxSend(function(event, jqXHR, ajaxOptions) {
if(ajaxOptions.context) {
ajaxOptions.context.data = "additional_key=additional_value&" + ajaxOptions.context.data;
} else {
ajaxOptions.data = "additional_key=additional_value&" + ajaxOptions.data;
}
});
$.ajax({
'url': 'test.php',
'data': {'foo':'bar'},
'type': 'POST'
});
Inspection:
Key Value
additional_key additional_value
foo bar
Edit: Tested with JQuery 1.7.1 I've noticed that you're running a lower version of jQuery.
$(document).ready(function() {
$(document).ajaxSend(function(event, jqXHR, ajaxOptions) {
if (ajaxOptions.extraData) {
ajaxOptions.extraData.additional_key = 'additional_value';
}
});
});
This only work for me (jQuery 1.4.4)

Function called by jQuery Form Plugin's beforeSubmit not returning value

The beforeSubmit function in my jQuery Form plugin needs to check whether the selected file already exists on the server. Here's that relevant code:
$('#frmSermonUpload').ajaxForm({
beforeSubmit: function() {
// Reset errors and clear messages
ClearForm(false);
var formValid = true,
fileExists = CheckFileExists();
console.log('beforeSubmit fileExists: ' + fileExists);
if (fileExists === 'true') {
$('#uploadedFile').addClass('inputError');
$('#fileErrorMsg').append(' A file with that name already exists on the server.');
formValid = false;
} else {
if (!ValidateUploadForm()) {
formValid = false;
}
}
console.log('formValid: ' + formValid);
if (!formValid) {
return false;
}
},
...
Here's the CheckFileExists() function:
function CheckFileExists() {
var fileName = $('#uploadedFile').val().replace(/C:\\fakepath\\/i, ''),
dataString;
dataString = 'checkFileExists=' + fileName;
console.log('fileName: ' + fileName);
console.log('dataString: ' + dataString);
$.ajax({
type: 'POST',
url: '../scripts/sermonUpload.php',
data: dataString,
success: function(serverResult) {
console.log('serverResult: ' + serverResult);
if (serverResult === 'existsTrue') {
return 'true';
} else {
return 'false';
}
},
error: function(xhr, status, error) {
alert('An error occurred while attempting to determine if the selected file exists. Please try again.);
}
});
//console.log('Current value of returnResult: ' + returnResult);
//return returnResult;
}
As you can see I'm using console output to check what's going on. In the CheckFileExists() function, fileName and dataString are being reported correctly. On the PHP side, I know that the POST data is getting there due to some logging I've got going on there.
Here's the PHP code that uses the POST data:
if (isset($_POST['checkFileExists']) && $_POST['checkFileExists'] !== '') {
$log->lwrite('**Checking if file exists.**');
$fileToCheck = $targetPath . $_POST['checkFileExists'];
$log->lwrite('file_exists: ' . file_exists($fileToCheck));
if (file_exists($fileToCheck)) {
echo 'existsTrue';
} else {
echo 'existsFalse';
}
}
What's happening is, in the console, the line console.log('beforeSubmit fileExists: ' + fileExists); is returning "undefined" (beforeSubmit fileExists: undefined).
Here's all of the console output for an upload where the file already exists, so the beforeSubmit should be stopped:
fileName: 042913sermon.mp3
dataString; checkFileExists=042913sermon.mp3
beforeSubmit fileExists: undefined
formValid: true
serverResult: existsTrue
It must be significant that the serverResult line is displaying after everything else. Does that have to do with how long the ajax call takes? If so, is there a way to delay the rest of the script until the ajax call is done executing?
UPDATE
As aorlando pointed out, the order of the console output signified that I needed to add async: false to my $.ajax call. After doing so, the console output was correct, but the function CheckFileExists() is still getting reported as undefined in beforeSubmit.
Ok. Now the problem is the scope of return.
If you use "async: false" you can return in this way (not so elegant)
var returnValue='';
$.ajax({
type: 'POST',
url: '../scripts/sermonUpload.php',
data: dataString,
async: false,
success: function(serverResult) {
console.log('serverResult: ' + serverResult);
if (serverResult === 'existsTrue') {
returnValue = 'true';
} else {
returnValue= 'false';
}
},
error: function(xhr, status, error) {
alert('An error occurred while attempting to determine if the selected file exists. Please try again.);
}
});
return returnValue;
You must declare a var returnValue out of the scope of the ajax call. Inside the ajax function you can modify the value of returnValue;
This is a solution which use closure, a quite complex javascript feature. Further read something about scope of a variable in javascript: What is the scope of variables in JavaScript?
This is not a very nice solution; is better if you call a function inside "success" function of ajax call as my previous example.
That's all folks!
You are using an AJAX async call.
Your method CheckFileExists()n return a value before the ajax call complete.
So the simplest solutions is to use:
$.ajax({
type: 'POST',
url: '../scripts/sermonUpload.php',
data: dataString,
async: false ...
if you want to use async call (the default as you can see: http://api.jquery.com/jQuery.ajax/
you must call (for ex.) a postcall function in the success function of the ajax call:
success: function(serverResult) {
console.log('serverResult: ' + serverResult);
if (serverResult === 'existsTrue') {
postFn('true');
} else {
postFn('false');
}
}, ...
Be carefull with the scope of the postFn
funcion postFn(_result){
console.log(_result);
}
I hope to be clear.
That's all folks!

How can I handle errors in AJAX in jquery

How can I handle errors in AJAX?
In my code, the else condition containing console.log is not executed even when the departments.json file is not loaded. I checked it by deleting the departments.json file from where it is loaded into the code.
My code is:
$.getJSON("departments.json?" + new Date().getTime(), {}, function(departments, status, xhr) {
if (xhr.status == 200) {
var numericDepts = [];
var nonNumericDepts = [];
for(dept in departments) {
$("#kss-spinner").css({'display':'none'});
if (isNaN(departments[dept].depNo)) {
if (isNaN(parseInt(departments[dept].depNo,10)))
nonNumericDepts[nonNumericDepts.length] = departments[dept];
else
numericDepts[numericDepts.length] = departments[dept];
}
else
numericDepts[numericDepts.length] = departments[dept];
}
numericDepts.sort(cmp_dept);
nonNumericDepts.sort(function(dept1,dept2) {
return dept1.depNo.toLowerCase() - dept2.depNo.toLowerCase();
});
departments.sort(cmp_dept);
var k = 0;
$.each(numericDepts.concat(nonNumericDepts), function() {
if (k % 2 == 0) {
$('<p class="odd" onClick="selectTag(this,\'' + this.id + '\', 1)">' + this.depNo + '</p>').appendTo($(".scroller", $("#br1")));
}
else {
$('<p class="even" onClick="selectTag(this,\'' + this.id + '\', 1)">' + this.depNo + '</p>').appendTo($(".scroller", $("#br1")));
}
k++;
});
$("#kss-spinner").css({'display':'none'});
}
else {
console.log(xhr.status);
console.log(xhr.response);
console.log(xhr.responseText)
console.log(xhr.statusText);
console.log('json not loaded');
}
});
You could just use the generic ajax() function:
$.ajax({
url: url,
dataType: 'json',
data: data,
success: successCallback,
error: errorCallback
});
You will need to use the fail() method in order to accomplish that.
Example:
$.get("test.php")
.done(function(){ alert("$.get succeeded"); })
.fail(function(){ alert("$.get failed!"); });
if you need a generic error handler use
$.ajaxSetup({
error: function(xhr, status, error) {
// your handling code goes here
}
});
JQuery's getJSON function is an abstraction over the regular .ajax() method - but it excludes the error callback.
Basically, the function you define is only called if the call is successful (that's why it never gets to the else part).
To handle errors, set an error handler before like this:
$.ajaxError(function(event, jqXHR, ajaxSettings, thrownError) { alert("error");});
Whenever an AJAX request completes with an error, the function will be called.
You can also append the .error at the end of your getJSON call:
$.getJSON("example.json", function() {
(...)
}).error(function() { (...) });
The $.getJSON() function is just a special purpose version of the more general .ajax() function.
.ajax() function will give you the extra functionality you desire (such as an error function). You can read more documentation here http://api.jquery.com/jQuery.ajax/
$.ajax({
url: "departments.json?" + new Date().getTime(),
dataType: 'json',
success: function(departments){
var numericDepts = [];
var nonNumericDepts = [];
for(dept in departments)
{
$("#kss-spinner").css({'display':'none'});
if(isNaN(departments[dept].depNo))
{
if(isNaN(parseInt(departments[dept].depNo,10)))
nonNumericDepts[nonNumericDepts.length]=departments[dept];
else
numericDepts[numericDepts.length]=departments[dept];
}
else
numericDepts[numericDepts.length]=departments[dept];
}
numericDepts.sort(cmp_dept);
nonNumericDepts.sort(function(dept1,dept2) {
return dept1.depNo.toLowerCase() - dept2.depNo.toLowerCase();
});
departments.sort(cmp_dept);
var k=0;
$.each(numericDepts.concat(nonNumericDepts),function(){
if(k%2==0){
$('<p class="odd" onClick="selectTag(this,\''+this.id+'\',1)">'+this.depNo+'</p>').appendTo($(".scroller",$("#br1")));
} else {
$('<p class="even" onClick="selectTag(this,\''+this.id+'\',1)">'+this.depNo+'</p>').appendTo($(".scroller",$("#br1")));
}
k++;
});
$("#kss-spinner").css({'display':'none'});
},
error: function(xhr, textStatus, errorThrown) {
console.log(xhr.status);
console.log(xhr.response);
console.log(xhr.responseText)
console.log(xhr.statusText);
console.log('json not loaded');
}
});​

Categories

Resources