CakePHP AJAX-Call: An error occured: undefined - javascript

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).

Related

fooplugins/Footable - "Cannot read property 'name' of null" when trying to load the table from JSON

I want to use the plugin "FooTable" with ajax calls.
Everything works fine when I hardcode the JSON, or even load it from a JSON file with $.get('....json'). When I try to load the table content from my server, I always get the error message "Cannot read property 'name' of null" shown with details here:
Error message
The image above also shows the JSON logged into the Console. I've tried loading it in a lot of different ways (in back- and front-end), but I just cant get it to work. I left some of my tries commented out in the attached Code.
JavaScript:
$(document).ready(function () {
jQuery(function ($) {
var ft = FooTable.init('.table', {
"columns": $.get('/js/mycols.json'),
//"rows": $.get('/js/myrows.json')
"rows": $.get('/api/GetEvents', function (e) {
console.log(JSON.parse(e.value));
//ft.rows.load(JSON.parse(e.value));
}, "json")
});
//$.ajax({
// url: "/api/GetEvents",
// dataType: "json",
// type: "GET"
//}).done(function (e) {
// console.log(e);
// ft.rows.load(e.value);
//})
});
});
ASP.NET Backend:
List<JObject> objList = new List<JObject>();
foreach (var e in events)
{
JObject jObj = JObject.FromObject(new
{
name = e.Name,
veranstaltungstyp = e.Type,
startzeit = e.StartTime.ToString("H:mm - dd MMMM yyyy"),
ende = e.EndTime.ToString("H:mm - dd MMMM yyyy"),
erstelltvon = e.CreatedBy.FirstName + " " + e.CreatedBy.LastName,
render = "placeholder"
});
objList.Add(jObj);
}
var result = new JsonResult(JsonConvert.SerializeObject(objList));
result.ContentType = "json";
result.StatusCode = 200;
result.SerializerSettings = new JsonSerializerOptions();
return Json(result);
I had a similar issue. It appears that FooTable is trying to load the rows before the table has been fully rendered and so it is not able to properly access the DOM.
Try wrapping your fetch in a on('ready.ft.table').
$(document).ready(function () {
jQuery(function ($) {
var ft = FooTable.init('.table', {
"columns": $.get('/js/mycols.json'),
});
$('.table').on('ready.ft.table', function(e) {
$.ajax({
url: "/api/GetEvents",
dataType: "json",
type: "GET"
}).done(function (e) {
console.log(e);
ft.rows.load(e.value);
})
});
});
});

Error part in jQuery is missing

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.

PHP variable to JS with JSON

I am having a very tough time transfering a php variable to javascript through json.
I have debugged it throughly and Ive come to the conclusion that something must be wrong with the javascript code. I am saying this because I output the json encoding in my php and see that I get {"result":"4","success":true}, where 4 is the variable value.
But when I try to get the variable in javascript like this:
$('#add').on('submit',function(){
var that = $(this), contents = that.serialize;
console.log("after serialize");
$.ajax({
url: 'caradded.php',
contentType: 'json',
data : contents,
type: 'post',
success : function(data){
/*
try {
var result = JSON.parse(data);
alert(result);
} catch (e) {
alert("Output is not valid JSON: " + data);
}*/
console.log("result0!! " + data.result);
console.log("result1!! " + data);
try{
localStorage.setItem("storageName",data);
} catch (e) {
alert("couldnt set item: " + data);
}
}
});
/*
error: function (request, error) {
alert(" Can't do because: " + error);
},
*/
//dataType: 'json',
//data: contents,
//So we do not submit data:
//return false;
// console.log(arguments);
});
then I get the following output on submit (a form submission):
result0!! null
result1!! [Object object]
The following is my php json encoding:
header("Content-type:application/json");
echo json_encode(array(
'result' => $GLOBALS['price'],
'success' => true
));
exit();
If I change $GLOBALS['price'] with a string like "test" then it works just fine. Again note that $GLOBALS['price'] outputs a value in my console.
Anyone who has any idea what Im doing wrong?
Thank you very much!
Best regards
William.

Identify 400-request with ajax

I'm having the following problem:
I am grabbing tweets from twitter, using their API. Whenever I've hit the limit of requests, it is returning me a 400 (Bad request) - reply.
Now, how can I find out whether a 400-reply was returned? The callback 'Error' isn't triggered.
$.ajax({
url: 'http://api.twitter.com/1/statuses/user_timeline/' + Followed[Index] + '.json?count=' + Tweetlimit + '&include_rts=true',
dataType: 'jsonp',
success: function (json) {
$.each(json, function (index, tweet) {
var date = Date.parse(tweet.created_at);
Tweets.created_at = date.toString('hh.mm.ss - dd/MM/yy');
Tweets.created_as_date = date;
Tweets.push(tweet);
})
CompletedUsers = CompletedUsers + 1;
},
error: function () {
alert("Error");
},
});
success is called when request succeeds. error is called when request fails. So, in your case, request succeeded and success is called. Now, if you want to respond to specific codes, you should follow this example in addition to your code:
$.ajax({
statusCode: {
404: function() {
alert("page not found");
}
}
});

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!

Categories

Resources