Ajax Success Fails to Initiate - javascript

I have a simple ajax post to the server..
$(".invite-team-members-submit-btn").click(function() {
$.post("invite_team_member", { token: $("#token").val(), email: $("#email").val(), team: $("#team").val() })
.done(function (responseText) {
responseText = jQuery.parseJSON(responseText);
alert(responseText.response);
})
.fail(function (data) { alert("ERROR: " + data); })
.then(function () { alert("Something should happen."); });
});
The JSON returned looks like this...
{"response":"Person has been invited."}
My response header in the console looks like this...
Response Headers
Cache-Control max-age=0, private, must-revalidate
Connection close
Content-Type application/json; charset=utf-8
Date Wed, 22 May 2013 21:45:07 GMT
Etag "e5b5e12acbcc78372b2a861027b66c05"
Status 200 OK
Transfer-Encoding chunked
X-Request-Id d835ce021eff7733d67ebfcdd468bdf2
X-Runtime 0.007909
x-ua-compatible IE=Edge
In my console I see that it the server and returned the appropriate text, but I don't receive an alert in my browser. I'm just out of idea's on what's wrong. Has jQuery updated something that I'm missing?

You are using $.post incorrectly. You mean to use $.ajax and specify the type: "post" property.
$.post's first argument is the URL. In your case it's an object. I think that perhaps jQuery ends up using the current page URL to make a request instead (which is why you see one), but I can't be sure. You could rewrite this as:
$.post("invite_team_member", {data: data})
.done(function (responseText) { alert(responseText); })
.fail(function (data) { alert("ERROR: " + data); });

use $.ajax() then set the type to "POST"

Try this code:
mydata = "name=Jon&location=USA";
$.ajax({
type : 'POST',
url : 'myphp.php',
data : mydata
}).done(function(msg){
alert("DONE");
});

Related

Rails is not parsing _method and authenticity_token form data fiels

I'm using axios to send requets and my current task is to send request for DELETing user. so i made a button and a function that triggers on click.
sendRequest(e) {
const token = document.querySelector("meta[name=csrf-token]").getAttribute('content');
axios.post('/users/2', {
_method: 'DELETE',
authenticity_token: token,
}).then(response => {
console.log(response)
});
}
According to rails docs:
When parsing POSTed data, Rails will take into account the special
_method parameter and act as if the HTTP method was the one specified inside it ("DELETE" in this example).
But after sending the request, i've got an error in console:
ActionController::RoutingError (No route matches [POST] "/users/2"):
UPD 1:
Just tried simple $.ajax request:
const token = document.querySelector("meta[name=csrf-token]").getAttribute('content');
$.ajax({
method: "POST",
url: "/users/2.json",
data: { _method: "delete", authenticity_token: token }
})
.done(function( msg ) {
alert( "Data Saved: " + msg );
})
and it works great. What's the difference than between axios post and ajax post requests so rails woun't parse axios _method field?

jQuery ajax call to mvc Action doesn't fire success/error

Trying to create a switch for a global session variable the ajax call never returns "success" nor "error".
The actions are called and the Session keys are set, but the success/error functions are never fired.
It is weird because I use the same structure with other calls to replace divs and it works.
Javascript
doesn't work
function SwitchHelpMode() {
debugger;
var helpmode = true;
$.ajax({
type: 'GET',
url: '/Session/GetSessionKey',
contentType: "application/json; charset=utf-8",
dataType: "json",
data: { key: "helpmode" },
sucess: function (data) {
alert(data);
//debugger;
//var ok = data.success;
//if (ok) {
// var algo = data.value;
// alert(algo);
// helpmode = !algo;
//}
},
error: function (xhr) {
//debugger;
alert(xhr);
alert('ERROR::SetSessionKey!' + xhr.responseText);
}
});
helpmode = false;
$.ajax({
type: 'GET',
url: '/Session/SetSessionKey',
data: { key: "helpmode", value: helpmode },
sucess: function (data) {
alert(data);
},
error: function (xhr) {
debugger;
alert('ERROR::SetSessionKey!' + xhr.responseText);
}
});
}
Controller
public ActionResult SetSessionKey(string key, string value)
{
Session[key] = value;
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
public ActionResult GetSessionKey(string key)
{
if(Session[key] != null)
{
var value = Session[key];
return Json(new { success = true, data = value }, JsonRequestBehavior.AllowGet);
}
else
{
return Json(new { success = false }, JsonRequestBehavior.AllowGet);
}
}
Javascript works
function FilterInfoByFlightsCallback(values) {
//debugger;
var data = JSON.stringify(values);
var url = '/Campaign/FilterInfoByFlights';
$.ajax({
type: 'GET',
url: url,
data: { filter: data },
success: function (result) {
$('#infoList').html(result);
},
error: function (result) {
// handle errors
location.href = "/MindMonitor/"
}
});
}
Responses from inspector
http://localhost:50518/Session/GetSessionKey?key=helpmode
{"success":true,"data":"false"}
http://localhost:50518/Session/SetSessionKey?key=helpmode&value=false
{"success":true}
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?
UzpcVlNTb3VyY2VcUHJvamVrdGVcTU1JXGJmdWVudGVzXE1NSVxNaW5kc2hhcmUuTU1JXE1NSVxTZXNzaW9uXEdldFNlc3Npb25LZXk=?=
Persistent-Auth: true
X-Powered-By: ASP.NET
WWW-Authenticate: Negotiate oRswGaADCgEAoxIEEAEAAABDh+CIwTbjqQAAAAA=
Date: Tue, 07 Jul 2015 12:45:03 GMT
Content-Length: 31
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?
UzpcVlNTb3VyY2VcUHJvamVrdGVcTU1JXGJmdWVudGVzXE1NSVxNaW5kc2hhcmUuTU1JXE1NSVxTZXNzaW9uXFNldFNlc3Npb25LZXk=?=
Persistent-Auth: true
X-Powered-By: ASP.NET
WWW-Authenticate: Negotiate oRswGaADCgEAoxIEEAEAAABDh+CIwTbjqQAAAAA=
Date: Tue, 07 Jul 2015 12:45:03 GMT
Content-Length: 16
Any idea?
There is no extra c in - sucess: function (data) { because of this even though the response from server would be 200 OK but it will not fire traditional success because it is not able to find one.
It should be - success: function (data) {
AJAX can be difficult to troubleshoot if you don't have a lot of experience with it. The Developer Tools (or FireBug) available for all modern browsers are your friend. They make it much easier to see/understand what the server is returning as a response.
Since the request is using Ajax, the browser won't render any error pages that are returned.
Using Chrome (the other tools are similar and usually opened with CTRL + SHIFT + I or F12):
Open the Developer Tools pane with (CTRL + SHIFT + I).
Click the Network tab.
Click your page element to fire the click handler and send the Ajax request.
Find and click the network request in the Network tab (bottom-left).
The pane next to the network request has Tabs for 'Headers', 'Preview' and 'Response'.
Headers will show you the contents of the request (what got sent to the server).
Response will show you the content of the servers response. This might be JSON for a successful request or it might be HTML source for an error page if an error occured.
The Preview tab will render the servers Response (if possible). This is especially helpful if you receive an error response/page from the server since you won't have to wade through the raw HTML to find the error details.
If your AJAX call is failing, and your server returns a 500 error, you can always check your server logs or look at the Network > Preview tab to see the error detail that is returned. You can troubleshoot the error just as you would any traditional server response.

jQuery.ajax to $http

I used this function
jQuery.ajax({
type: 'POST',
url: urlSubmit,
timeout: 5000,
dataType: 'text',
data: {
date : dataDate,
url : dataUrl,
domaine : dataDomaine,
email : dataEmail,
destinataire : dataDestinataire,
msg : dataMsg
},
"success": function (jqXHR, textStatus, errorThrown) {
console.log("AJAX success :) - statut " + textStatus);
$timeout(successMailZR_alerte, 3000);
},
"error": function (jqXHR, textStatus, errorThrown) {
console.log("AJAX fail :/ - statut " + textStatus);
$timeout(errorMailZR_alerte, 3000);
}
});
Whats the code is doing : code POST to a php script who send an email.
but, since i rewrited my code in a complete angularjs app, i do it like this :
$http({
method: 'POST',
url: urlSubmit,
timeout: 5000,
cache: false,
data: {
date : dataDate,
url : dataUrl,
domaine : dataDomaine,
email : dataEmail,
destinataire : dataDestinataire,
msg : dataMsg
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
responseType: 'text',
}).
success(function(data, status, headers, config) {
console.log("AJAX success :) - statut " + status);
$timeout(successMailZR_alerte, 3000);
}).
error(function(data, status, headers, config) {
console.log("AJAX fail :/ - statut " + status);
$timeout(errorMailZR_alerte, 3000);
});
Problem is : with $http, i have a success 200 but nothing is posted and i have no return in my email. What's the problem ?
The problem is that jQuery's POST does send your data as form data (e.g. key-value pairs) (https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms/Sending_and_retrieving_form_data) whereas AngularJS sends your data in the request payload. For a difference between the two see the following SO question: What's the difference between "Request Payload" vs "Form Data" as seen in Chrome dev tools Network tab
In order to make your angular script works with your server you have to convert your data to a URL encoded string as described here: How can I post data as form data instead of a request payload?. Simply setting headers: {'Content-Type': 'application/x-www-form-urlencoded'} is not enough.
A different approach would be to adapt the back-end of your application to parse the message payload instead of the form data parameters.
To understand this one need to understand the request headers set by angular and jquery, There are differences with the headers like when request is post by jQuery then header might look like this:
POST /some-path HTTP/1.1
Content-Type: application/x-www-form-urlencoded // default header set by jQuery
foo=bar&name=John
You can see this in form data in the request made in the browser, if you use chrome then you can see this in chrome inspector at network tab, if you click the request then you can see the form data and content headers set by the jQuery.
On the other side with angular js $http service, when a request is made then you can find these:
POST /some-path HTTP/1.1
Content-Type: application/json // default header set by angular
{ "foo" : "bar", "name" : "John" }
The real difference is this you have a request payload not usual form data which is used by jQuery. so you need to do something extra at the server side like below.
Use this:
$data = json_decode(file_get_contents("php://input"));
echo $data->date;
// and all other params you have sent
This is due to its default headers
Accept: application/json, text/plain, * / *
Content-Type: application/json
and jQuery unlikely have something else:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8

jQuery AJAX and handling different dataTypes

I'm using ASP.Net MVC, but this applies to any framework.
I'm making an Ajax call to my server, which most of the time returns plain old HTML, however if there is an error, I'd like it to return a JSON object with a status message (and a few other things). There doesn't appear to be a way for the dataType option in the jQuery call to handle this well. By default it seems to parse everything as html, leading to a <div> being populated with "{ status: 'error', message: 'something bad happened'}".
[Edit] Ignoring the dataType object and letting jQuery figure out doesn't work either. It views the type of the result as a string and treats it as HTML.
One solution I came up with is to attempt to parse the result object as JSON. If that works we know it's a JSON object. If it throws an exception, it's HTML:
$.ajax({
data: {},
success: function(data, textStatus) {
try {
var errorObj = JSON.parse(data);
handleError(errorObj);
} catch(ex) {
$('#results').html(data);
}
},
dataType: 'html', // sometimes it is 'json' :-/
url: '/home/AjaxTest',
type: 'POST'
});
However, using an Exception in that way strikes me as pretty bad design (and unintuitive to say the least). Is there a better way? I thought of wrapping the entire response in a JSON object, but in this circumstance, I don't think that's an option.
Here's the solution that I got from Steve Willcock:
// ASP.NET MVC Action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AjaxTest(int magic) {
try {
var someVal = GetValue();
return PartialView("DataPage", someVal);
} catch (Exception ex) {
this.HttpContext.Response.StatusCode = 500;
return Json(new { status = "Error", message = ex.Message });
}
}
// jQuery call:
$.ajax({
data: {},
success: function(data, textStatus) {
$('#results').html(data);
},
error: function() {
var errorObj = JSON.parse(XMLHttpRequest.responseText);
handleError(errorObj);
},
dataType: 'html',
url: '/home/AjaxTest',
type: 'POST'
});
For your JSON errors you could return a 500 status code from the server rather than a 200. Then the jquery client code can use the error: handler on the $.ajax function for error handling. On a 500 response you can parse the JSON error object from the responseText, on a 200 response you can just bung your HTML in a div as normal.
While Steve's idea is a good one, I'm adding this in for completeness.
It appears that if you specify a dataType of json but return HTML, jQuery handles it fine.
I tested this theory with the following code:
if($_GET['type'] == 'json') {
header('Content-type: application/json');
print '{"test":"hi"}';
exit;
} else {
header('Content-type: text/html');
print '<html><body><b>Test</b></body></html>';
exit;
}
The $_GET['type'] is just so I can control what to return while testing. In your situation you'd return one or the other depending on whether things went right or wrong. Past that, with this jQuery code:
$.ajax({
url: 'php.php?type=html', // return HTML in this test
dataType: 'json',
success: function(d) {
console.log(typeof d); // 'xml'
}
});
Even though we specified JSON as the dataType, jQuery (1.3.2) figures out that its not that.
$.ajax({
url: 'php.php?type=json',
dataType: 'json',
success: function(d) {
console.log(typeof d); // 'object'
}
});
So you could take advantage of this (as far as I know) undocumented behavior to do what you want.
But why not return only JSON regardless of the status (success or error) on the POST and the use a GET to display the results? It seems like a better approach if you ask me.
Or you could always return a JSON response, and have one parameter as the HTML content.
Something like:
{
"success" : true,
"errormessage" : "",
"html" : "<div>blah</div>",
}
I think you'd only have to escape double quotes in the html value, and the json parser would undo that for you.
I ran into this exact same issue with MVC/Ajax/JQuery and wanting to use multiple dataTypes (JSON and HTML). I have a AJAX request to uses an HTML dataType to return the data, but I attempt convert the data that comes back from the ajax request to a JSON object. I have a function like this that I call from my success callback:
_tryParseJson: function (data) {
var jsonObject;
try {
jsonObject = jQuery.parseJSON(data);
}
catch (err) {
}
return jsonObject;
}
I then assume that if the jsonObject and errorMessage property exist, that an error occured, otherwise an error did not occur.
I accomplished this by using the ajax success and error callbacks only. This way I can have mixed strings and json objects responses from the server.
Below I'm prepared to accept json, but if I get a status of "parsererror" (meaning jquery couldn't parse the incoming code as json since that's what I was expecting), but it got a request status of "OK" (200), then I handle the response as a string. Any thing other than a "parsererror" and "OK", I handle as an error.
$.ajax({
dataType: 'json',
url: '/ajax/test',
success: function (resp) {
// your response json object, see if status was set to error
if (resp.status == 'error') {
// log the detail error for the dev, and show the user a fail
console.log(resp);
$('#results').html('error occurred');
}
// you could handle other cases here
// or use a switch statement on the status value
},
error: function(request, status, error) {
// if json parse error and a 200 response, we expect this is our string
if(status == "parsererror" && request.statusText == "OK") {
$('#results').html(request.responseText);
} else {
// again an error, but now more detailed and not a parser error
// and we'll log for dev and show the user a fail
console.log(status + ": " + error.message);
$('#results').html('error occurred');
}
}
});

Can I evaluate the response type of an $.ajax() call in success callback?

I am using jQuery to make an AJAX request to a remote endpoint. That endpoint will return a JSON object if there is a failure and that object will describe the failure. If the request is successful it will return HTML or XML.
I see how to define the expected request type in jQuery as part of the $.ajax() call. Is there a way to detect the request type in the success handler?
$.ajax(
{
type: "DELETE",
url: "/SomeEndpoint",
//dataType: "html",
data:
{
"Param2": param0val,
"Param1": param1val
},
success: function(data) {
//data could be JSON or XML/HTML
},
error: function(res, textStatus, errorThrown) {
alert('failed... :(');
}
}
);
Have you application generate correct Content-Type headers (application/json, text/xml, etc) and handle those in your success callback. Maybe something like this will work?
xhr = $.ajax(
{
//SNIP
success: function(data) {
var ct = xhr.getResponseHeader('Content-Type');
if (ct == 'application/json') {
//deserialize as JSON and continue
} else if (ct == 'text/xml') {
//deserialize as XML and continue
}
},
//SNIP
);
Untested, but it's worth a shot.
how about using the complete option?
$.ajax({
...
complete : function(xhr, status) {
// status is either "success" or "error"
// complete is fired after success or error functions
// xhr is the xhr object itself
var header = xhr.getResponseHeader('Content-Type');
},
...
});
By the time it calls your success handler, the data has already been deserialized for you. You need to always return the same data type for any successful result. If there truly is an error, you should probably throw an exception and let it get handled by the error callback instead. This should be able to parse the resulting error and package it for your callback, that is, it will detect that the response did not have 200 OK status and parse the result to obtain the error information.

Categories