Callbacks on Ajax.BeginForm don't work right - ajax

why do I always have so much trouble...? given that I didn't solve the problem in my other article, I decided to just code the javascript right into the values... so I have:
OnSuccess="alert('ok')",
OnFailure="alert('failed')",
so my problem is the submission works fine; a record gets inserted into the database and I get a callback... but I get the wrong callback! I get a failure even though the record got inserted. heeeeelp!

You should be able to read data from the response to figure out why it's considered a failure:
OnFailure="handleError",
...
function handleError(ajaxContext) {
var response = ajaxContext.get_response();
var statusCode = response.get_statusCode();
alert("Sorry, the request failed with status code " + statusCode);
}
Alternatively, use Fiddler and look at the response. Make sure the status code, content type and content are all as expected.

ok, I figured out a few things:
OnFailure="handleError" is the correct way to do this (see the other article I mentioned for resolution)
ajaxContext didn't have a get_response() method because I was actually hooking up the function to the OnComplete event instead (my bad)! once hooked up to the OnSuccess, I get my controller's method Json return value natively
I was getting the OnSuccess handler called when the database entry was failing. this is because my controller method was try{} catch{}ing and therefore never failed! me being dopey :(

Related

How to inject a header from the errormessage

I've been attempting to inject a custom header for a error response status (and failing).
I have a very simple lambda being used
exports.handler = (event, context, callback) => {
// TODO implement
//callback(null, 'Hello from Lambda');
var error = {
name:"error",
message:"I am a failure",
statusCode: 400
};
error["x-test"] = 'foo';
callback(JSON.stringify(error), null);
};
In the api gateway, I've done the following:
set up CORS to include x-test
responsetemplate = "$input.path('$.errorMessage')"
responseparameter to include:
method.response.header.x-test = integration.response.body.x-test
Also, I have a statusCode mapped using '.*statusCode.*?400.*'
This has turned out empty.
so I decided to take a step back and see what happens if I do:
method.response.header.x-test = integration.response.body
I found that I get the stringified response of errorMessage.
{"x-test":"{\"errorMessage\":\"{\\\"name\\\":\\\"error\\\",\\\"message\\\":\\\"I am a failure\\\",\\\"statusCode\\\":400,\\\"x-test\\\":\\\"foo\\\"}\"}"}
So I decided to change the responsetemplate to force it to json by doing the following:
responsetemplate = "$util.parseJson($input.path('$.errorMessage'))"
and I still get the stringified response:
{"x-test":"{\"errorMessage\":\"{\\\"name\\\":\\\"error\\\",\\\"message\\\":\\\"I am a failure\\\",\\\"statusCode\\\":400,\\\"x-test\\\":\\\"foo\\\"}\"}"}
My guess is that it doesn't transform as expected, but only for the final output.
So how would you take a value and shove it into a header?
Thanks,
Kelly
I think this is more of a design choice regarding the limitation imposed by both Lambda and APIGateway. I will try my best to walk through my thoughts.
First of all, in Lambda, callback(error, result) function can either take an error string as first argument, or an object as result response. If you want to pass along a simple error message, you could definitely just do that. However, in your case, as you tried to pass along an entire error object, choosing the second option is clearly a better solution (in contrast to stringifying an object and parse it into object again). As a result, the final line of your Lambda function should be:
callback(null, error);
Yes, in this case, if you test your function in Lambda, the output result will no longer be red and flag it as an error, but this won't matter as you can format your headers and response in APIGateway.
Now you need to set things up in APIGateway, in which you need to make use of the object passed by Lambda.
It's actually rather easy to use method execution interface to configure headers.
In Method Response, you need to add the headers you want to include in the response for a specific status code, which in your case is x-test. (If you want the API to return different status codes, you can also configure that in this panel.)
Then go to Integration Response, under the same status code, you will see the added header available. According to this documentation from AWS, you can use integration.response.body.JSONPath_EXPRESSION to assign the header value (this is another reason that you should return object rather than string in Lambda, as there is no formal API to parse object from string at this stage). This time, as your Lambda is passing an object, the value of x-test header is:
integration.response.body['x-test']
Now your API should have the proper header included.
NOTE: In order to set up different status code in APIGateway, you should leave some distinguishable data fields (your statusCode: 400 should work perfectly) in you response body, so you can use RegEx to match those fields to a specific status code.
So... above doesn't work with success message. I found this blog though talking about error handling design pattern. Apparently what they suggest is only mapping status code when there is an error, in which case no body should be passed (only the errorMessage), as browser won't care about response body for a status code other than 200 anyway.
I guess after all, it is impossible to customize both status code and header at the same time with Lambda passing an object to APIGateway?
This is due to the fact that you are stringifying the error object coming from your Lambda function. API Gateway attempts to resolve the JSON-Path expression and can't evaluate "x-test" in a string. If you return an object instead of a string, this should work.
You may want to consider using proxy integrations which allow you to control the headers and status directly from your Lambda function.
Update: I've written a blog post on this topic with sample code # https://rpgreen.wordpress.com/2017/01/25/how-to-send-response-headers-for-aws-lambda-function-exceptions-in-api-gateway/

500 error even request render HTML code

Using ajax to get HTML content from GSP template .
$.get(url,{word:$('#search').val()},fnback)
The browser Console raises 500 error .
However , we get the expected response , but in browser not in callback .
Known that this kind of error appears only in production environment .
This question is related to this ticket
The error is caused either by Grails or by your application, you will need to determine why; it certainly seems to be happening relatively late in the pipeline since you are getting the correct HTML back (I assume you aren't explicitly rendering a 500 status code in your code by accident).
As for the response you are getting back, it is ignored due to the 500 status. The $.get function accepts a callback which is only invoked on successful requests. If you put debug lines into your fnback function you will see it is never called. If you were to replace the $.get with an equivalent $.ajax call and provide an error callback, that function would get the HTML you are seeing returned in the browser's dev tools.
Based on #Gregor Petrin answer :
$.get(myurl,{word:word},function(d){
$('div#resp').html(d)
})
has been replaced by :
$.ajax({url:myurl,data:{word:word}}).always(function(d,status){
if(status !=='success'){
d=d.responseText;
}
$('div#resp').html(d);
});

Parse.com Cloud Code custom method call result undefined

I've got an afterSave handler in Cloud Code that conditionally calls a custom method.
From my testing, both functions appear to be working exactly as desired. The custom method is skipped appropriately (with confirming console messages looking correct). It is also called appropriately, and the custom method creates a new object exactly as desired.
What's confusing me is that when the custom method IS called, I get something like the following in my Cloud Code log:
Input: {"title":"title","ownerId":"ownerId"}
Result: undefined
Like I said, the values seem to be passed in correctly, and the method seems to run correctly, but I don't understand why I get Result: undefined.
In the method that is called, I've placed a response.success() or response.error() in every pathway that's possible.
So, is this something to worry about?
The custom method is a "fire-and-forget" type of method, so my afterSave method doesn't wait around for a response. Is that why I'm getting Result: undefined?
The reason you are getting undefined is because your response and error functions don't pass any values. Replace it with this.
success: function(result) {
//...
response.success(result);
},
error: function(error) {
response.error(error);
}
Then you'll no longer have an undefined result.

Ember.js REST Ajax Success and Error

I'd like to know what the success and error do in the Ember.js RESTAdapter's ajax function.
hash.success = function(json) {
Ember.run(null, resolve, json);
};
hash.error = function(jqXHR, textStatus, errorThrown) {
Ember.run(null, reject, jqXHR);
};
I know hash is the data sent through AJAX, but what role do success and error play? I assume they'd be run based on a successful or erroneous AJAX response, right? They're set before the AJAX is called, as callbacks? How do they work?
but what role do success and error play? I assume they'd be run based on a successful or erroneous AJAX response, right?
Right, since ember uses jQuery under the hood the functions mentioned are just plain jQuery methods.
They're set before the AJAX is called, as callbacks? How do they work?
As for the functions itself, see this info taken from the jQuery official docs:
error callback option is invoked, if the request fails. It receives the jqXHR, a string indicating the error type, and an exception object if applicable. Some built-in errors will provide a string as the exception object: "abort", "timeout", "No Transport".
success callback option is invoked, if the request succeeds. It receives the returned data, a string containing the success code, and the jqXHR object.
I should also mention that the success callback is in recently jQuery version being replaced with done and is marked as deprecated as noted here:
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are deprecated as of jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
But don't worry, because I guess until jQuery removes this methods completely the ember team has surely catched up with the new callback versions.
And finally if you where wondering what the call to Ember.run does you can have a look here. But basically it ensures that the passed target and method are run inside of a RunLoop, ensuring also any deferred actions like bindings and views updates, this are flushed at the end. This SO answer on the Runloop is also very informative.
Hope it helps.

jquery ajax error json response

i have jquery global error event set, like following:
$("#message_alert").ajaxError(function(event, XMLHttpRequest, settings, thrownError){
ajax_error(XMLHttpRequest);
});
and ajax_error method gets the XMLHttpRequest parameter totally fine init. now the request which XMLHttpRequest gets, it also have json data from the backend in XMLHttpRequest.responseText
now i want to know, how can i parse this json data, i tried doing
eval("var request = "+XMLHttpRequest.responseText);
which for some reason was working fine, but dose not work anymore and i know for sure that data is getting back to ajax response. maybe something im doing wrong.. well firebug shows following error from it, i dont know what im doing wrong
Error:
missing ; before statement
http://basit.io.im/javascript/global.js
Line 127
btw this is the same eval line number. any ideas?
Have you tried -
eval("var request = XMLHttpRequest.responseText");
That should fix the error you are getting.

Resources