Return data from POST - javascript

I'm running a Flask server. A JS file send data to the server through POST requests. This is the server code:
#app.route('/approve', methods=['POST'])
def approve():
try:
assignmentId = request.form['assignmentId']
response = client.approve_assignment(
AssignmentId=assignmentId
)
return make_response(jsonify(response), response['ResponseMetadata']['HTTPStatusCode'])
except ClientError as e:
return make_response(jsonify(e.response), e.response['ResponseMetadata']['HTTPStatusCode'])
In JS, I want to have an alert to notify whether the action was successful or not; and if fail then what is the specific error. However, the returned data is empty and I could not check it to notify the user of specific error.
$.post("http://cronus.eecs.northwestern.edu/mturk/approve",
{assignmentId: assignmentId,
OverrideRejection: false},
function(data, status) {
console.log(data);
console.log(status);
if (status == 200) {
alert("Approved successfully");
} else {
alert("Error");
}
});
How could I fix this? Is data null because I didn't use the correct response object in Flask code?

You should use .fail for this.
$.post( "example.php", function() {
alert( "success" );
})
.done(function() {
alert( "second success" );
})
.fail(function(error) {
alert( `error ${error}` );
})
.always(function() {
alert( "finished" );
});

I hope this can help you.
var request = $.ajax({
url: url,
method: 'post',
data: {...},
});
request.done(function(message) {
alert(message);
});
request.fail(function(error) {
alert(error);
});

Related

post request on form with validation

i built a registration form and validated it using javaScript. but i want after a user filled the form, it should post to the server. i am confused on where to place my httpRequest function. i don't know if its after validation or inside the validation function
This is my validation function
function formregister(e){
if (first_name.value=== "" || last_name.value=== "" || user_id.value==="" || id_type.value=== ""
|| id_no.value=== "" || address.value==="" || !terms.checked) {
var fPassResult = '1';
} else{
var fPassResult = '0';
}
if(fPassResult === "1") {
window.location = "register.html";
}else{
Swal.fire({
type: 'success',
title: 'Your Registration has been Submitted Successfully',
text: 'Click Ok to Login',
timer: 10000
}
).then(function(){
window.location="Login.html";
})
}
e.preventDefault();
};
**And this is my post request function**
function registerationApiCall(e){
var data = {
"user_id":"user_id.value",
"user_pin": "user_pin.value",
"first_name":"first_name.value",
"last_name":"last_name.value",
"address":"address.value",
};
fetch("jehvah/api",{
type : 'POST',
data : data,
dataType : 'JSON',
encode : true,
success: function (response, status, xhr) {
if (result==="OK") {
console.log("success");
}else{
console.log("bad");
}
},
error: function (xhr, status, error) {
console.log("something went wrong");
}
});
}
Please kindly check my post request function, i dont know if i am doing it the right way
Hi ✌ when fPassResult === "0" in this case inside else{} call registerationApiCall()
you tell the user it's a success after you get OK from the server which is Asynchronous call
& inside fetch response you call swal.fire
for this code to work your server when checks the database & every thing is ok returns a msg like this {"msg":"OK"}
CODE:
else{
registerationApiCall()
}
function registerationApiCall becomes
fetch('jehvah/api',
{ method: 'POST',headers: {'Content-Type': 'application/json'}, body: JSON.stringify(data)})
.then((response) => response.json())
.then((result) => {
console.log('Success:', result);
if (result.msg="OK") {
console.log("success");
Swal.fire({
type: 'success',
title: 'Your Registration has been Submitted Successfully',
text: 'Click Ok to Login',
timer: 10000
}).then(function(){window.location="Login.html";})
}else{ console.log("usres exsists / etc");}
})
.catch((error) => {
console.log("something went wrong");
});
}
Also in the request payload you sent a group of strings not the variables containing the form values
Here
var data = {
"user_id":"user_id.value",
"user_pin": "user_pin.value",
"first_name":"first_name.value",
"last_name":"last_name.value",
"address":"address.value",
};
Change that to
var data = {
"user_id":user_id.value,
"user_pin": user_pin.value,
"first_name":first_name.value,
"last_name":last_name.value,
"address":address.value
};
Looking at the fetch documentation (https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch), success and error does not exists.
The fetch function returns a Promise, so you can handle results as any Promise should do:
fetch("jehvah/api", {
method: 'POST',
body : JSON.stringify(myDataObject)
})
.then(blob => blob .json())
.then(result => console.log('Success!!))
.catch(e => console.log('Failure :('))

How to get a browser alert message with angularjs and nodemailer

I am trying to get an alert with after sending an email with nodemailer and not just the json response. Here is what I have so far:
app.js (nodejswith nodemailermodule):
transporter.sendMail(mailOptions, (error) => {
if (error) {
res.sendStatus(500)
} else {
res.sendStatus(200)
}
transporter.close();
});
});
angularjs:
$http.post({
url: '/contactUs',
data: '',
}).then(
function successCallback(response) {
$scope.alert("Message Sent!!")
},
function errorCallback(response) {}
)
you'll need to just call alert("Message Sent") instead of $scope.alert("Message Sent").
If you want it to be angularized, you can inject $window and call $window.alert("Message Sent") which will make it easier on you if you're unit testing.

angualrjs how to ignore status 400 after POST success

Is there a way to ignore or bypass this error code 400 and just trigger a function when this error occurs?
I tried this : --
vm.createOrder = function () {
var deferred = $q.defer(); // update
orderService.createOrder()
.then(function (response, status) {
deferred.resolve(response); // update
if(status == 400) {
console.log('Should never happen but trigger a function anyway! ');
localStorage.clear();
}
console.log('Successfully created an order: ', response.status);
})
}
orderService: --
createOrder: function () {
return $http({
url: 'apiURL',
method: 'POST'
})
}
but it doesn't even console.log the string in the if(status) condition or in the success, but the POST method does go through so its posting the data I want to post but it returns an error code of 400.
Edit fixed
orderService.createOrder()
.then(function (response) {
console.log('Successfully created an order: ', response.status);
})
.catch(function (e) {
console.log('Should never happen but trigger a function anyway! ');
localStorage.clear();
console.log(e);
})
Your service should look like this.
createOrder: function () {
return $http.post('SomeURL')
.then(function (response) {
return response.data;
},
function (response) {
return $q.reject(response);
});
}
You should call it like this, rather than a try catch.
orderService.createOrder().then(function(response){
//Successfull Call
},function(response){
//Error on call
});

How to handle laravel TokenMismatchException when session expires

When the session is expired, User cant log back in without a page refresh because the _token in ajax headers is expired(AKA TokenMismatchException). I cant handle the exception by redirecting user to a log in page because the login is an overlay modal and the request is handled via ajax.
I thought i could catch the mismatch exception in Handler.php and return a json response with a session token. and on the client side, use the new token to continue the intended process. However, when i use the new token passed from server, the session token will be changed again on server side which results another TokenMismatchException.
So how should i handle the exception in a secured way without refreshing a page?
Here's what i have right now:
setup csrf_token in a global js file:
$(function () {
$.ajaxSetup({
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content') }
});
});
render method in app/exceptions/handler.php:
public function render($request, Exception $e)
{
if ($this->isHttpException($e))
{
return $this->renderHttpException($e);
}
else if ($e instanceof TokenMismatchException)
{
if ($request->ajax()) {
return response()->json([
'message' => 'TokenMismatchException',
'token' => csrf_token()
]);
}
}
else
{
return parent::render($request, $e);
}
}
in authentication.js:
$.ajax({
type: "POST",
url: "/auth/login",
data: {
"email" : $('#login_email').val(),
"password" : $('#login_password').val(),
'remember': $('#login_remember').is(':checked')
},
success: function(response) {
if (response.message === 'TokenMismatchException') {
console.log(response); //message and token exist
//if catch the exception, use the new token to set up the ajax headers and login again
$.ajaxSettings.headers["X-CSRF-TOKEN"] = response.token;
console.log($.ajaxSettings.headers["X-CSRF-TOKEN"]);
$.ajax({
type: "POST",
url: "/auth/login",
data: {
"email" : $('#login_email').val(),
"password" : $('#login_password').val(),
'remember': $('#login_remember').is(':checked'),
},
success: function(res) {
console.log(res);
},
error: function(err) {
console.log(err);
}
});
}
console.log('logged in');
},
error: function(xhr, status, err) {
}
});
thanks in advance.
In your render function, you've to check for a specific TokenMismatchException. So may be you can try something like this:
if ($exception instanceof \Illuminate\Session\TokenMismatchException) {
return response()->json('msg', 'Your session has expired. Please try again.');
}
You may also pass a new csrf_token along with the json so that you can replace the old one with the new one and send the form request again.
if ($exception instanceof \Illuminate\Session\TokenMismatchException) {
return response()->json(['msg'=> 'Your session has expired. Please try again.', 'token'=> csrf_token()]);
}
I haven't tested this code. But this should get you started.
Also, if you want, you can use a package: https://github.com/GeneaLabs/laravel-caffeine

Amplifyjs and status code

I'm trying to use "Amplifyjs" to handle AJAX requests as does John Papa in his Pluralsight course but I'm having problems with authentication.
I am using form authentication. Everything works fine.
My problem comes with the unauthenticated requests. I can not find a way to make "amplifyjs" give back to the error function the http code (401, 403 ...) to distinguish requests that failed because they were not authenticated from requests that failed because did not met the business logic.
A request example would be:
amplify.request.define("products", "ajax", {
url: "/api/Products",
datatype: "json",
type: "GET"
});
amplify.request({
resourceId: "products",
success: callbacks.success,
error: function (datos, status) {
//somecode
}
});
Thank you.
You can create a decoder if you want the XHR object and pass that along. It will have the error code and other information you may need.
amplify.request.define("products", "ajax", {
url: "http://httpstat.us/401",
datatype: "json",
type: "GET",
decoder: function ( data, status, xhr, success, error ) {
if ( status === "success" ) {
success( data, xhr );
} else if ( status === "fail" || status === "error" ) {
error( status, xhr );
} else {
error( status, xhr );
}
}
});
amplify.request({
resourceId: "products",
success: function(data, status) {
console.log(data, status);
},
error: function(status, xhr) {
console.log(status, xhr);
}
});​
You can test the above code by looking at this http://jsfiddle.net/fWkhM/
Thanks for your answer.
Finally, as I saw no one answered me I did something similar to what you propose:
var decoder = function (data, status, xhr, success, error) {
if (status === "success") {
success(data, status);
} else if (status === "fail" || status === "error") {
try {
if (xhr.status === 401) {
status = "NotAuthorized";
}
error(JSON.parse(xhr.responseText), status);
} catch (er) {
error(xhr.responseText, status);
}
}
};
After I modify the default decoder:
amplify.request.decoders._default = decoders.HeladeriaDecoder;
And in the error callback I managed the returned status.
error: function (response, status) {
if (status === "NotAuthorized") {
logger.error(config.toasts.errorNotAuthenticated);
} else {
logger.error(config.toasts.errorSavingData);
}
//more code...
}

Categories