How do I call a method in Scala through javascript & ajax? - ajax

I do not know if my title was perhaps a little misleading. But here's what I really need help with.
I'm making a get on this url:
$.get("/fb/login/"+fbEmail, function(data){
console.log(data);
});
This is my routes:
GET /fb/login/:email presentation.controllers.Auth.authenticateSocialNetwork(email:String)
And here's my action:
def authenticateSocialNetwork(email:String) = Action {
if(!editorRepo.getEditorByEmail(email).isEmpty){
Redirect(routes.Profile.editorProfile).withSession(Security.username -> email)
} else {
Redirect(routes.Profile.initiatorProfile).withSession(Security.username -> email)
}
}
My expectation from this is that my action gets called and fires of what's inside it. In other words, Redirecting.
But what actually happens, which is not so illogical, is that my $.get call gets a response with my redirect's.
How do I actually call my action-method, without sending a response to javascript?
Here's my function in javascript, posting this snippet for it to be more clear in our discussion in the comments above.
function addClickToLoginButtons(){
$("#loginWithFb").click(function(){
FB.login(function(response){
if(response.authResponse){
FB.api('/me', function(response){
var fbEmail = response.email;
$.get("/fb/isRegisteredAtNetwork/"+fbEmail+"/facebook", function(data){
if(data == "true"){
if(confirm("Do you want to log with facebook-account "+fbEmail+"?")){
$.get("/fb/login/"+fbEmail, function(data){ *//HERE'S WHERE I WOULD WANT TO CALL MY METHOD IN SCALA*
console.log(data);
});
} else {
console.log("try again with a different facebook-account");
} //end confirm else
} else {
console.log("Logged in not in database");
}//end get else
});
});
} else {
console.log("permission not granted");
} // end authResponse else
}, {scope: 'email'});
});
}

In your action, instead of returning Redirect, return Ok(urlToBeRedirectedTo).withSession(...). Once this response received in the javascript code, do your stuff and then call window.location = urlToBeRedirectedTo;.
This will add the email to the session, and will redirect to the wanted URL.

Related

ajax post not trapping errors, always trapping success

I have an ajax post method to ad new records to a database, the process itself works ok and my server side code traps errors (duplicate input, etc). When an eror happens, the ajax method doesnt 'see' it, the 'success' function is always called. This is my ajax post method
$.ajax({
url: '#Url.Action("Add", "Organisation")',
data: $form.serialize(),
async: true,
type: 'POST',
error: function (returnval) {
$form.parents('.bootbox').modal('hide');
bootbox.alert('There was an error saving this organisation : ' + returnval['responseText']);
},
success: function (returnval) {
// Hide the dialog
$form.parents('.bootbox').modal('hide');
bootbox.alert('New Organisation successfully added');
}
})
and the actionmethod on my controller
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult Add(OrganisationEditCreateViewModel data)
{
InsertOrganisationRequest request = new InsertOrganisationRequest();
IEnumerable<ModelError> allErrors = ModelState.Values.SelectMany(v => v.Errors);
if (ModelState.IsValid)
{
var model = mapper.Map<OrganisationEditCreateViewModel, OrganisationDto>(data);
request.organisation = model;
var response = this._organisationService.InsertOrganisation(request);
if (response.isSuccess)
{
return Json(new { success = true, responseText = "New organisation added successfully" }, JsonRequestBehavior.AllowGet);
}
else
{
return Json(new { success = false, responseText = "Error adding new organisation : " + response.Message }, JsonRequestBehavior.AllowGet);
}
}
return Json(new { success = false, responseText = "Error adding new organisation : Invalid input" }, JsonRequestBehavior.AllowGet);
}
so when I insert a duplicate record, the serverside code traps this and this branch of code is returned back to my ajax call
return Json(new { success = false, responseText = "Error adding new organisation : " + response.Message }, JsonRequestBehavior.AllowGet);
but the ajax call always calls this bit of code
success: function (returnval) {
// Hide the dialog
$form.parents('.bootbox').modal('hide');
bootbox.alert('New Organisation successfully added');
}
the error part never gets called, what am I doing wrong ?
Update your success method!
success: function (returnval)
{
if(returnval.success=true)
{
// Hide the dialog
$form.parents('.bootbox').modal('hide');
bootbox.alert('New Organisation successfully added');
}
if(returnval.success=false)
{
$form.parents('.bootbox').modal('hide');
bootbox.alert('There was an error saving this organisation : ' + returnval['responseText']);
}
}
hope helps!
You are not doing anything wrong.Actually your code is also working fine,the
reason is Success function always getting executing because your AJAX call successfully happening.
If AJAX call failed then only error function will get execute.
Example suppose if you gave Ajax attribute contentType wrong
ex:- contentType:'xyzfds';
in some scenario or may be because of any another ajax method attribute wrong value.So no need to worry about it.
If you want to display your error message then follow below approach it may help you.Thank You
success: function (returnval) {
if(returnval!=null){
if(returnval.success){
// Hide the dialog
$form.parents('.bootbox').modal('hide');
bootbox.alert('New Organisation successfully added');
}
if(returnval.success==false){
$form.parents('.bootbox').modal('hide');
bootbox.alert('There was an error saving this organisation : ' + returnval['responseText']);
}
}
}

WebAPI redirect not working?

I'm trying the following:
[System.Web.Http.AcceptVerbs("PUT")]
public HttpResponseMessage MakePost(PostDto post) {
try {
var response = Request.CreateResponse(HttpStatusCode.Redirect); // tried MOVED too
response.Headers.Location = new Uri("google.com");
return response;
} catch (Exception e) {
ErrorSignal.FromCurrentContext().Raise(e);
return Request.CreateResponse(HttpStatusCode.InternalServerError, e);
}
}
Which seems to be partially working - when this is called, I see the POST request in chrome debugger. Nothing appears in the Response tab, but then I see a GET request sent to the new URI, yet the page never changes, and my AJAX call throws an error:
var options = {
url: postUrl,
type: type,
dataType: 'json',
xhrFields: {
withCredentials: true
}
};
return $.ajax(options)
.done(function (response) {
// do stuff
})
.fail(function (response) {
alert('error) // this gets hit - shouldn't the browser have redirected at this point?
}).complete(function () {
// stuff
});
};
If I inspect response, I see a Status 200 "OK".... I'm so confused.
What am I doing wrong?
This happens because the code issuing the AJAX request follows the redirect, not the browser. This will then fail because the AJAX request tries to access a different domain. If you want to redirect the browser, you should return some JSON result or a custom HTTP header, manually pick this up in your jQuery, and do the redirect there.
In your controller:
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Headers.Add("FORCE_REDIRECT", "http://google.com");
Then add a success callback to your AJAX call:
success: function(data, textStatus, jqXHR) {
if (jqXHR.getResponseHeader('FORCE_REDIRECT') !== null){
window.location = jqXHR.getResponseHeader('FORCE_REDIRECT');
return;
}
}
In the past, I've wrapped the controller result up in a custom action result class for reuse.

Alert is coming before response

I have this ajax function which validates the user provided key. but the alert comes before the ajax response and due to which if the user provide a wrong key even can get access
$(document).ready(function() {
$('#submit').click(function(e) {
e.preventDefault();
var key = $('#downloadkey').val();
var dataString = {KEY:key};
$.ajax({
url: "/mediabox/home/validate_key",
type: 'POST',
data: dataString,
success: function(msg) {
if(msg=="true")
{
alert("do something");
}
else
{
alert("Your download key is either wrong or you didn't provide it.");
return false;
}
}
});
});
});
What makes you believe the alert is coming before the response? The success handler is only invoked after the response has been successfully received client-side.
To confirm, you can edit your success handler to log the response:
success: function(msg) {
console.log(msg);
if(msg=="true")
{
alert("do something");
}
else
{
alert("Your download key is either wrong or you didn't provide it.");
return false;
}
}
Also, if you're using the return false to deny access to the user by blocking the HTML action that, won't work due to the asynchronous nature of AJAX.
The success function is called when the request completes.
success(data, textStatus, jqXHR)Function, Array
A function to be called if the request succeeds. The function gets passed three
arguments: The data returned from the server, formatted according to
the dataType parameter; a string describing the status; and the jqXHR
(in jQuery 1.4.x, XMLHttpRequest) object. As of jQuery 1.5, the
success setting can accept an array of functions. Each function will
be called in turn. This is an Ajax Event.
The code within the success handler will only execute once the AJAX request is completed. If you are getting an alert before hand then that indicates that the request completed properly.

Can a jQuery $.post call itself again from the callback?

The use case would be if the response it gets isn't what it wanted it can call itself again.
$.post(qrLoginAjax.ajaxurl, {
userID : '11234324'
},function( response ) {
if (response.userID != 'undefined'){
//do stuff
} else {
// call $.post again
}
});
How would I do that?
Thanks
You could do something like this:
var sendAjax = function() {
$.post('/foo', function(result) {
if (response.userID != 'undefined') {
// do stuff
} else {
// resend the AJAX request by calling the sendAjax function again
sendAjax();
}
});
};
sendAjax();
But sending AJAX requests like this seems like a bad design decision in my opinion. You should ensure that you don't get into an infinite recursion by using for example a number of retries counter.
You can make it a function, and call itself. For example with $.ajax, you can do this:
function do_stuff(){
$.ajax({
url: 'ajax.php',
success: function(data){
// Stuff
},
error: function(){
do_stuff();
}
});
}
This is the general principle of a recursive function, but it is highly recommended that you test conditions or set a maximum number of tries so it doesn't get stuck in an infinite loop.
Use this keyword of Javascript. As we all know, that refers to the object it belongs to. For example:
$.post(qrLoginAjax.ajaxurl,
{
userID : '11234324'
},
function( response ) {
if (response.userID != 'undefined') {
//do stuff
}
else {
$.post(this);
}
}
);

Smarty jQuery/Ajax call barrier

I'm modifying an existing system which uses Smarty. This particular problem is causing a major stumbling block as I just can't find a way around it.
I have a data-grid, each record has an action which calls ?module=the_module&action=the_action.
My corresponding function function the_module_the_action($postData, $getData) is used to perform the particular request.
The request for this module comes through from a jQuery $.ajax({}) request, simply because I don't want to loose the search form variables. So on success, I'll redirect the page using document.location='index.php?module=&action='.
This is fine as it allows me to detect that the action has been successful whilst maintaining the search filters on the grid.
But, I have a problem when the user action fails. The method the_module_the_action($postData, $getData) return echo 'success'; exit() on success but on a failure it should print out the Smarty template i.e. details of the record.
I believe the problem occurs because of a call through Ajax. The template is being served but because it is a call made using Ajax it isn't displayed.
How can I get around this problem?
Update:-
This is my function which Ajax calls:
public function module_action($post_data) {
$object=new Class((int)$post_data["id"]);
if($object->method()) {
echo "success";
exit();
}
else {
$this->assignToSmarty('_someSmartyVar', $someData);
$this->assignToSmarty('_data', $class->getData());
echo "failed";
}
}
The Ajax used to call this is:-
$(document).ready(function() {
$(".revokeButton").click(function(){
var selected=$(this).attr('id');
var filterBu = $('#filter_bu').val();
var filterJc = $('#filter_jc').val();
if(confirm("Are you sure you want to r.....")) {
$.ajax({
beforeSend: function() { },
url: 'index.php?module=module&action=action',
type: 'POST',
data: ({ bid:selected }),
cache: false,
success: function(data, textStatus) {
if(data == 'success') {
success_message = 'success';
} else if(data == 'failed') {
success_message = 'failed';
}
document.location='index.php?module=module&message='+success_message+'&filter_bu='+filterBu+'&filter_jc='+filterJc;
}
});
}
});
});
The success and failure are echoing out successfully, but the smarty stuff isn't.
I see two problems. First of all, you seem to have forgotten the smarty->display() function call in the failure leg of the module_action function. Secondly, you wrote:
if(data == 'success') {
success_message = 'success';
} else if(data == 'failed') {
success_message = 'failed';
}
This will always only output success or failure. You probably want to do something more like the following:
if(data == 'success') {
success_message = 'success';
} else {
// if got here, 'data' doesn't contain "success!", so it must contain
// something else, likely error data. You could either just display
// data as it is or first do some sort of check to ensure that it
// does, in fact, contain error data, and then display it.
success_message = 'error!<br \>\n' + data;
}

Resources