How to pass and use a success/failure response with AJAX - phoenix-framework

I'm replacing the standard server-side form with AJAX. I have them working but now I would like to pass a success/error message from the server that I can use in the client.
My client AJAX code is:
var csrf = $('input.csrf').val();
$.ajax({
url: '/unauthmessages',
type: 'post',
data: { message: { name: name, message: message } },
headers: {
'X-CSRF-TOKEN': csrf
},
dataType: 'json',
success: function (data) {
console.log(data);
}
})
My controller action is:
def create(conn, %{"message" => message_params}) do
messageChangeset = Message.changeset(%Message{}, message_params)
case Repo.insert(messageChangeset) do
{:ok, _message} ->
conn
|> put_flash(:info, "Success")
|> redirect(to: "/us#vpageContactos")
{:error, messageChangeset} ->
vpage = "contactos"
render(conn, FabASA.PageView, "us.html", messageChangeset: messageChangeset, vpage: vpage)
end
end
How to change the controller / success function to pass/use success/error messages?

The render/redirects as you have above doesn't work as the AJAX considers the the response content as simple data which will be returned along with the success/error status, rather than pages that need to be displayed. Also, the redirect will be silently followed by the AJAX call, and you'll end up seeing the content of the page you're redirecting to as data rather than the browser page redirecting.
IMHO the best way to handle this is to return your intent as a JSON response, which the client side JS will know what to do with depending on the success/error status.
For example, you could return something like the following in your controller:
def create(conn, %{"message" => message_params}) do
messageChangeset = Message.changeset(%Message{}, message_params)
case Repo.insert(messageChangeset) do
{:ok, _message} ->
conn
|> put_flash(:info, "Success")
|> json(%{redirect_to: "/us#vpageContactos"})
{:error, messageChangeset} ->
conn
|> put_status(:bad_request)
|> json(errors_in(changeset))
end
end
# NOTE: The following should probably be in ErrorHelpers
defp errors_in(%{errors: errors}) do
translated_errors = for {field, message} <- errors, into: %{}, do: {field, MyApp.ErrorHelpers.translate_error(message)}
%{errors: translated_errors}
end
defp errors_in(_), do: %{}
Then, in your client side call, you can do something like:
var csrf = $('input.csrf').val();
$.ajax({
url: '/unauthmessages',
type: 'post',
data: { message: { name: name, message: message } },
headers: { 'X-CSRF-TOKEN': csrf },
dataType: 'json',
success: function(data) {
window.location.href = data.redirect_to;
},
error: function(xhr) {
var errors = xhr.responseJSON();
// Show the errors to the client
}
})

Related

ajax post request to view

I am trying to make a simple ajax request to a view but keep having a not Found error for the given url:
Not Found: /myapp/start_session/1/scan_ports/
"POST /myapp/start_session/1/scan_ports/ HTTP/1.1" 404 5711
js
$(document).ready(function() {
$.ajax({
method: 'POST',
url: 'scan_ports/',
data: {'csrfmiddlewaretoken': '{{csrf_token}}'},
success: function (data) {
alert("OK!");
},
error: function (data) {
alert("NOT OK!");
}
});
});
url
url(r'^scan_ports/$',views.ScanPorts,name='scan_ports'),
view
#login_required
def ScanPorts(request):
user = request.user
if request.method == 'POST':
currentSetting = models.UserSetting.objects.filter(isCurrent=True)
if currentSetting.serialPort:
print("GOT IT!")
return HttpResponse('')
Is the ajax request not set properly?
Assuming you are in the "myapp" app, replace:
method: 'POST',
url: 'scan_ports/',
for this:
method: 'POST',
url: '/myapp/scan_ports/',
First check your urls, the url on which you posted is incorrect hence 404 not found error.
Try to define your url in your JS as: {% url 'scan_ports' %} which will search your urls with the name your provided in urls.py
In addition, this may not be a good approach to submit a form via ajax.
Your JS should be something like this:
$('.form-class-name').on('submit', function (e) {
e.preventDefault();
console.log("ajax is called");
$.ajax({
type: $(this).attr('method'),
url: "/url-name/",
data: $(this).serialize(),
dataType: 'json',
success: function(data) {
alert("success");
},
error: function(data) {
alert("Failure");
}
})
}
e.preventDefault() prevents the natural/default action, and prevents from submitting the form twice.
.serialize(), serializes the form data in a json format.
append a "/" before and after your action url.
Your view must return a dictionary as ajax deals with JSON format.
Edit your view like this:
if request.method == "POST":
currentSetting = models.UserSetting.objects.filter(isCurrent=True)
if currentSetting.serialPort:
print("GOT IT!")
a = {'data':'success'}
return HttpResponse(json.dumps(a))
This will return a dictionary required by the ajax.

Getting data from get request?

I'm sending an ajax request like so:
$.ajax({
type: "GET",
url:"/game/set",
data: JSON.stringify({colour: col, size: size}),
success: function(){console.log("SUCCESS.")},
dataType: 'json'
});
I can receive the request on the server just fine, but I can't figure out how to pull the data from it before responding. He is how I'm handling it.
var jsonString = '';
req.setEncoding('utf8');
req.on('data', function (data) {
jsonString += data;
});
req.on('end', function () {
reqData = JSON.parse(jsonString);
respond(200, JSON.stringify(reqData));
});
but I seem to get this error when trying to parse.
SyntaxError: Unexpected end of input
You can't send data in a GET request. Try POST instead.

How do django send ajax response?

Here is my code ,I got response is 200 OK but ajax came to error part
I can't figure it out
My html:
$(".statics").click(function(){
var name = $(this).attr("data-name");
$.ajax({
url: 'statics/',
data: {
'name':name
},
type: 'POST',
async: false,
dataType: 'json',
success: function(dataArr){
console.log("ssss:",dataArr)
if(dataArr == "IS_PASS"){
alert('PASS!');
}else if(dataArr == "NOT_PASS"){
alert('NOT_PASS');
}
},
error: function(ts){
console.log("eeee:",ts)
alert('fail');
},
});
});
My views.py
def statics_r(request):
if request.is_ajax():
name = request.POST['name']
...
if is_pass:
return HttpResponse("IS_PASS")
else:
return HttpResponse("NOT_PASS")
And the console is : eeee: Object {readyState: 4, responseText: "NOT_PASS", status: 200, statusText: "OK"}
Why it is not success???
For an ajax response, you should be returning json, the easiest way is to use the JsonResponse class instead of HttpResponse, or set the content_type
HttpResponse("{'result': 'IS_PASS'}", content_type="application/json")
You would need to adjust your success function to access the results, i.e dataArr.result

Ajax goes to error with status = 0, but Fiddler returns 200

Here's my code:
$.ajax({
type: "POST",
async: true,
url: "/MyController/MyMethod",
data: {
items: grid.getAllRowIds()
},
success: function (data) {
debugger;
},
error: function (a, b, c) {
debugger;
}
});
The parameters are correct because the method in the controller is entered, but ajax doesn't go to success. It goes to error instead, with status code = 0. Fiddler says everything is ok.
What is going on?
And the response text is empty string.

Resource interpreted as Script but transferred with MIME type text/xml

In VS 2010 i have two projects,one for webservice and another for asp.net pages.
i try to call a webservice (from the .js of an asp.net page) like this:
var host = "localhost:15932";
var url = "http://" + host + "/MyWebService.asmx/GetFeed?callback=?";
$.ajax({
async: true,
type: 'Get',
url: url,
data:{ CountryId: CountryId, FeedDateString: FeedDateString, Previous: Previous},
contentType: 'application/json; charset=utf-8',
//contentType:'text/xml ',
processData: true,
dataType: 'jsonp',
success: function (response) {
var result= response.d;
,
error: function (request, status, error) {
alert(request.responseText);
}
,
failure: function (msg) {
alert('somethin went wrong' + msg);
}
});
the call goes wel ,but the result returned from the webservice is xml ,and chrome shows an error message:"Resource interpreted as Script but transferred with MIME type text/xml"
i get an xml stream when i type this in my browser:
"http://localhost:15932/MyWebService.asmx/GetCountryFeed?callback=jsonp1339760946308&CountryId=1&FeedDateString=&Previous=true"
the code of my webservice method:
[WebMethod(Description = "Get feed")]
[ScriptMethod(ResponseFormat = ResponseFormat.Json,UseHttpGet=true)]
public List<Feed> GetFeed(int CountryId, string FeedDateString, bool Previous)
{
return (new UserFeedManager()).GetFeed(CountryId, FeeDate, Previous);
}
what to change to make the response.d in json format?
You need to override the web services response.
Set GetFeed's return type to void.
Serialize List.
Return the json:
HttpContext.Current.Response.ContentType = "text/javascript";
HttpContext.Current.Response.Write(json)
HttpContext.Current.Response.End();
You may want to create a class to handle your response's and pass in your functions that return json with a Func function or Func parameter.

Resources