I'm trying to get my project running on the localhost. I'm having a problem with the built-in ajax function upon success. Here is the javascript function:
function getDecisions(page, searchstring) {
page = typeof page !== 'undefined' ? page : 1;
searchstring = typeof searchstring !== 'undefined' ? searchstring : '';
$('.loading-container').show();
if (searchstring != '') {
params = searchstring;
}
else {
params = getFilterObj();
params['page'] = page;
//Only get checked types
$('#types input[type="checkbox"]').each(function() {
if ( $(this).is(":checked") ) {
params[$(this).attr("name")] = 'True';
}
});
}
if ( $('input[name="approved-only"]:checked').val() == 'yes' ) {
params['approved-only'] = 'yes';
}
$.ajax({
url:'/dh',
data: params,
success: function(data) {
info = data.info;
newhtml = '';
if (info.length == 0) {
newhtml += '<tr><td colspan="18" style="text-align: center;">No results returned</td></tr>\n';
}
...
}
I know that the javascript function is working as I'm stepping through until the very last line of the function, but I'm not even sure if the ajax function is being called. I'm getting the following Internal Server Error (500):
Can anyone say what could be causing a 500 error on the localhost for this type of an ajax call? Or how I might see whether the ajax function is being called?
The ajax call is definitely being made. The reason I know this is because you are seeing the 500 server error. The 500 server error is a response from the server that means the request had some kind of error at the server. It looks like you are debugging in chrome. If that is the case, you can go to the Network tab in the developer tools and then as you step through your code, you will see an entry appear for that request. When the request completes, you will see the status update with error 500, which should match up with what you were seeing in the console. You can then click on that entry in the network tab, and hopefully be able to see the actual response from the server.
If you have control over the server, you might also be able to debug the webservice at that side and see what is going on.
Related
When I visit a page that contains a button which makes a jQuery ajax $.post call for the first time, upon clicking on the button the expected URL is successfully hit and the action sends back the expected JsonResult. HOWEVER, the $.post immediately hits the error callback function before the action even runs (remember though, the action method DOES run, the result is simply not being awaited) and the error messages returned are null or empty strings. In other words, it should have hit the success callback but it hits the error callback instead. Hmmmm.
Here is the resultant alert statement:
": Server error. Could not vacate the locker. Try again."
If I hit the button a second time, again, the expected URL is (also still) hit, but this time the $.post (correctly) waits for the response before making the decision on whether to run the success or the error callback, and it ($.post) correctly calls the success call back function.
Here is the resultant alert statement:
"Locker C18 has been successfully vacated and unassigned."
Why is it doing this?
JavaScript/jQuery
$.post({
url: '#Url.Action("ReclaimAlocker", "Ajax")',
data: {
lockerId: id
},
success: function () {
alert('Locker ' + lockerNumber + ' has been successfully vacated and unassigned.');
location.reload();
},
error: function (a, b, c) {
alert(a.responseText + ' : ' + c + ' Server error. Could not vacate the locker. Try again.');
}
});
MVC Action (in a controller called AjaxController)
[HttpPost]
public JsonResult ReclaimAlocker(long lockerId)
{
var lockerAssignments = _amsDb.LockerAssignments.Where(k => k.Active && k.LockerId == lockerId).ToList();
foreach (var assignment in lockerAssignments)
{
assignment.Active = false;
assignment.DateRemoved = DateTime.Now;
_amsDb.Entry(assignment).State = EntityState.Modified;
}
var locker = _amsDb.Lockers.Find(lockerId);
if (locker != null)
{
locker.Occupied = false;
_amsDb.Entry(locker).State = EntityState.Modified;
}
_amsDb.SaveChanges();
return Json(true, JsonRequestBehavior.AllowGet);
}
Here is the info from the Network tab of Chrome Dev tools:
Name Status Type Initiator Size Time
-----------------------------------------------------------------------
1st attempt
ReclaimAlocker (canceled) xhr jquery.min.js:4 0 B 37ms
LockerAssignments 200 document Other 7.7KB 32ms
All subsequent attempts
ReclaimAlocker 200 xhr jquery.min.js:4 7.7KB 39ms
I have this jquery code in my view file
$('#ticket-ticket_impact_id').change(function() {
var priority = $('#ticket-ticket_priority_id :selected').val();
var impact = $('#ticket-ticket_impact_id :selected').val();
if ($('#ticket-ticket_priority_id').val() == '' || $('#ticket-ticket_impact_id').val() == '') {
} else {
$.post('index.php?r=support/ticket/ajax-ticket-sla&ticket_priority_id=' + priority + '&ticket_impact_id=' + impact);
}
})
$('#ticket-ticket_priority_id').change(function() {
var priority = $('#ticket-ticket_priority_id :selected').val();
var impact = $('#ticket-ticket_impact_id :selected').val();
if ($('#ticket-ticket_priority_id').val() == '' || $('#ticket-ticket_impact_id').val() == '') {
} else {
$.post('index.php?r=support/ticket/ajax-ticket-sla&ticket_priority_id=' + priority + '&ticket_impact_id=' + impact);
}
})
from here the value the of priority and impact id is sent to the controller/ajax function
public function actionAjaxTicketSla(){
$ticket_priority_id=$_REQUEST['ticket_priority_id'];
//var_dump($ticket_priority_id);die();
$ticket_impact_id=$_REQUEST['ticket_impact_id'];
if(Sla::find()->where(['ticket_priority_id'=>$ticket_priority_id,'ticket_impact_id'=>$ticket_impact_id])->exists())
{
} else{
echo '<script type="text/javascript">alert("No sla defined!");</script>';
}
}
I am not able to even echo something in response here don't know whats wrong here any help would be appreciated.
response
You are mixing POST , GET and REQUEST
in ajax you use a POST but don't send nothins as POST param
instead you pass param in url as GET params
and in action you look for REQUEST but not for GET (or post)
And you access directly to the $_REQUEST instead of using yii2 method for this
You should rethink you code ..
anyway just as a first step
looking to your ajax call you could use the param you pass as get param
public function actionAjaxTicketSla(){
$request = Yii::$app->request;
$get = $request->get();
$ticket_priority_id=$get['ticket_priority_id'];
//var_dump($ticket_priority_id);die();
$ticket_impact_id=$get['ticket_impact_id'];
if(Sla::find()->where(['ticket_priority_id'=>$ticket_priority_id,'ticket_impact_id'=>$ticket_impact_id])->exists())
{
echo 'OK';
} else{
echo 'No sla defined';
}
}
and in client post
$.post('index.php?r=support/ticket/ajax-ticket-sla&ticket_priority_id=' +
priority + '&ticket_impact_id=' + impact,
function(data){
if (data !='OK') {
alert(data);
}
});
Try Echo in the If condition also and share the "response" (of page) from Network console.
Sending javascript code from the PHP server to js isn't a good practice. What you are doing is essentially making a call to the server and sending it the data and not doing anything with the resposne you've received.
Try to create a proper callback function like shown in this example,
Add a callback function (AJAX is Asynchronous, so your return is being hit before there is any data to return):
function returnData(param) {
console.log(param);
}
Now add that callback function as a parameter to your AJAX function, and lets run it:
function getCartProduct(id, callback){
$.post('sever.php',
function(data){
callback(data);
});
}
getCartProduct(id, returnData);
Also the server's response is treated as a string in javascript. To evaluate it as a javascript syntax, pass the string into the eval() method.
eval('alert("this works");');
I'm having an issue where a modal window pops up in my browser after I return to the View from the controller. Here's what the window says (in Chrome):
It contains the html code from Index.cshtml page.
Here is the code in my controller:
public ActionResult Save(Events changedEvent,FormCollection actionValues)
{
string action_type = actionValues["!nativeeditor_status"];
var eventText = actionValues["text"];
var eventStart = actionValues["start_date"];
var eventEnd = actionValues["end_date"];
try
{
switch (action_type)
{
case "inserted":
if (User.IsInRole("Admin"))
db.Event.Add(changedEvent);
Send(eventText, eventStart, eventEnd);
break;
case "deleted":
//changedEvent = db.Event.SingleOrDefault(ev => ev.Id == source_id);
changedEvent = db.Event.SingleOrDefault(ev => ev.text == eventText);
db.Event.Remove(changedEvent);
break;
default: // update
//changedEvent = db.Event.SingleOrDefault(ev => ev.Id == source_id);
changedEvent = db.Event.SingleOrDefault(ev => ev.text == eventText);
UpdateModel(changedEvent);
break;
}
db.SaveChanges();
}
catch (Exception)
{
action_type = "error";
}
return RedirectToAction("Index", "Home");
}
Here is the code from my Index.cshtml page that handles saving to the database:
function init() {
var dp = new dataProcessor("/Home/Save");
dp.init(scheduler);
dp.setTransactionMode("POST", false);
}
I'm still fairly new to MVC and have completed a few tutorials but I have never ran into this behavior before. I was thinking I have to handle the callback from the controller but all my searching hasn't yielded anything so far. I'm hoping someone from this fine community can point me in the right direction.
Thank you for taking the time to read!
You won't be able to redirect from your C# controller if you are using an AJAX request (your dataProcessor is making an AJAX POST request internally).
You have two options:
1) Not to use your dataProcessor, and make a request to the server using the default C# MVC binding like this: https://stackoverflow.com/a/7856996/3638529. With this method, you will be able to return a RedirectToAction() and the user will be returned correctly, but this will probably change your infrastructure a lot.
2) Change your controller to return the url to redirect.
First change your save method to return something like this:
public ActionResult Save(Events changedEvent,FormCollection actionValues)
{
...
return Json(new {success = true, url = Url.Action("Index", "Home")});
}
Then change your JavaScript method to make something like this when your AJAX request is complete:
function myAwesomeSuccessCallback(response) {
if (response.success) {
window.location = response.url;
}
else {
//show error
}
}
I posted on the dhtmlx forum and I was able to get a solution from one of their support staff. I'm posting his answer in full below:
Hello,
here is what happens in your code
1) when you change something in scheduler (e.g. create/delete/modify event), scheduler sends a POST request to Home/Save, as defined in dataProcessor inside init() function()
2) dataProcessor sends post request and expects the server response to match a certain format of json or xml https://docs.dhtmlx.com/dataprocessor__ ... nsedetails
3) Your Save action outputs the html page instead of the expected response, this line:
return RedirectToAction("Index", "Home");
4) client-side fails to parse it as a valid response and pops up a message.
In order to fix the issue, you need to return a valid response from the Save action, it can be done by replacing your current response - return
CODE: SELECT ALL
RedirectToAction("Index", "Home"); //with this:
return Content(
new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(
new System.Collections.Generic.Dictionary<string, string>
{
{"action", action_type},
{"tid", eventId}
}
)
);
// will send response like this {"action":"updated", "tid":"5"} - which is valid response
Please note "tid" - eventId part, if you insert event into db - you have to send new database event it back to the client. If it's any other operation - you can either return the same id as came from the client or omit "tid" field from the response.
This did the trick for me. Thank you all for your comments and I hope my question helps someone else in the future.
So I have a JSON API that I put a variable in at the end, and if the variable is a "valid" username (if the account actually exists) it will return information about it, but if the account isn't valid/doesn't exist it returns {} and in the console of the website I'm accessing the API with it shows an error saying
Uncaught TypeError: Cannot read property 'steamID' of undefined
at XMLHttpRequest.profileCheck.onreadystatechange
So I was wondering how I can check if that error is returned with an if statement? For example something like if(typeError === true) { do code } else { something else};
Here's the code I'm using to access the API (if that's important at all):
function isID64() {
var id64 = document.getElementById("username").value;
var realID64;
var profileCheck = new XMLHttpRequest;
profileCheck.open("GET", "<api im using>" + id64);
profileCheck.onreadystatechange = function() {
if (profileCheck.readyState === 4) {
var profileCheckResponse = JSON.parse(profileCheck.responseText);
realID64 = profileCheckResponse.playerstats.steamID;
...
}
};
profileCheck.send();
}
Any help is appreciated :)
I think this type error is because you are using JSON file to send data from your back end (php or something). if user is not exist it sends either null or a string. but in front end JSON.parse statement expect an json variable. Do following thing in your back end
if(userexist())
//save data into json variable;
else
//save "User Not exist" into your json variable.
then change your code from frontend (Javascript)
if (profileCheck.readyState === 4)
{
var profileCheckResponse = JSON.parse(profileCheck.responseText);
if(profileCheckResponse[0]=="User Not Exist";
//Display Error
else
realID64 = profileCheckResponse.playerstats.steamID;
...
}
I am using the following code to do the cross domain AJAX request with YQL :
function requestCrossDomain( site, callback ) {
function cbFunc(data) {
// If we have something to work with...
alert("inside call back");
if ( data.results[0] ) {
// Strip out all script tags, for security reasons.
// BE VERY CAREFUL. This helps, but we should do more.
data = data.results[0].replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
// If the user passed a callback, and it
// is a function, call it, and send through the data var.
if ( typeof callback === 'function') {
callback(data);
}
}
// Else, Maybe we requested a site that doesn't exist, and nothing returned.
else throw new Error('Nothing returned from getJSON.');
}
// If no url was passed, exit.
if ( !site ) {
alert('No site was passed.');
return false;
}
// Take the provided url, and add it to a YQL query. Make sure you encode it!
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from html where url="' + site + '"') + '&format=xml&callback=cbFunc';
// Request that YSQL string, and run a callback function.
// Pass a defined function to prevent cache-busting.
$.getJSON( yql, cbFunc );
console.log("outside call back");
}
and calling the above as follow :
requestCrossDomain('http://www.cnn.com', function(results) {
alert(results);
});
When i am running the above code in firefox, although response (in firebug console) is showing the content of website inside callback function (cbFunc) yet it is showing nothing as alert.Also the result of console.log("inside call back") at line 5 is not printing in firebug console.
can anyone suggest me where things are going wrong or any explanation for above ?
btw i have already gone through :
http://tek-insight.blogspot.in/2010/05/cross-domain-ajax-request-proxy-json.html
http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-cross-domain-ajax-request-with-yql-and-jquery/
Possible explanation in related stackoverflow questions.
$.getJSON accepts as callback function for 'success' response. But if error were returned (404, 500, etc) then it will not call this function.
You need to add extra functions in order to catch other scenarios of responses:
$.getJSON( yql, cbFunc)
.done(function() { console.log( "second success" ); })
.fail(function(jqxhr, textStatus, error) { console.log( "error", textStatus, error ); })
.always(function() { console.log( "complete" ); });