jQuery ajax function return - javascript

I have this function that embeds flash :
function embedswfile(target, swf, base, width, height) {//dosomething}
And I want to call the function like this
embedSwf("flashgame",decode("<?=base64_encode($path['location'])?>"),decode("<?=base64_encode($path['base_directory'])?>"),"800","600" )
The idea is that whenever someone looks for any swf inside my website,he wont find anything clean.I will change the encoding algorithm,but this is just temporary. In order for that function to work,whenever I call the function 'decode' it must return a single value. PHP contains
<?php
echo base64_decode($_POST['s']);
?>
I tried this but it still wont work
var globvar;
function processdata(newmsg) {
globvar = newmsg;
}
function decode(s){
$.ajax({type: "POST",
url: "includes/decode.inc.php",
data: "s=" + s,
success:function(newmsg){
processdata(newmsg);
}
});
return globvar;
}

Important:
Forget about using Ajax and encoding, decoding the path. What do you think you gain from it? Security? No. One can figure out that this is bas64 encoded or he just monitors the network traffic and reads the response from the Ajax call.
Just do
embedSwf("flashgame","<? =$path['location']?>"),"<?=$path['base_directory']?>","800","600" )
Really, you cannot prevent someone else seeing the data and are just making things more complicated for you.
(Or you have to decrypt the data with JavaScript.)
(original answer is still correct nevertheless)
Ajax is asynchronous so something like var test = decode(s); will never work. The decode function will return before the Ajax call finishes.
Instead, put your logic into the callback handler. For example, if your code was this before:
var retdata = decode('s');
// here comes code that handles retdata
put the code into a function and call it from the success handler:
function process(retdata) {
// here comes code that handles retdata
}
function decode(s){
$.ajax({type: "POST",
url: "includes/decode.inc.php",
data: "s=" + s,
success:function(newmsg){
process(newmsg);
}
});
}
This seems to be a very common problem to all beginners. You will find a lot of questions here that deal with the same problem.
Update:
It is not nice, but you could change the function to
function decode(s, cb){
$.ajax({type: "POST",
url: "includes/decode.inc.php",
data: "s=" + s,
success:function(data){
cb(data);
}
});
}
and do
decode("<?=base64_encode($path['location'])?>", function(location) {
decode("<?=base64_encode($path['base_directory'])?>", function(dir) {
embedSwf("flashgame",location,dir,"800","600" );
});
});
Update 2:
For completeness, you can make the Ajax call synchronous, by using async: false. Then this will work:
function decode(s){
var ret;
$.ajax({type: "POST",
url: "includes/decode.inc.php",
data: "s=" + s,
async: false,
success:function(newmsg){
ret = newmsg;
}
});
return sync;
}
var val = decode(s);
However, this will block the browser until the Ajax call finished. You have to test whether this matters in your case or not.
Update 3:
You could also change your PHP script to not only accept one parameter but several and process both strings in one go.

Related

Waiting for ajax response same function

I know that similar questions have been posted many times, however I've read many of them and can't find an answer to my problem.
I have a function that waits for an ajax request response. Many of you will ask why? Well, I'm using a Wizard Jquery Plugin which executes a function onLeaveAStepFunction when a step is left, then the wizard goes to the selected step if the return value from onLeaveAStepFunction is true; else it remains in the same step.
I'm doing this async: false for waiting and it works, but this is a bad design. Also, I can't use a blockUI plugin.
How can I do this?
Some code:
Initializing the wizard:
$("#wizard").smartWizard({
onLeaveStep : onLeaveStepFunction,
});
Calling the ajax request:
function onLeaveStepCallback(obj, context) {
nextStep = sendForm();
}
The ajax request:
var nextStep = false;
$.ajax({
url : path,
type : "POST",
async : false,
data : $("#" + idForm).serialize(),
success : function(data) {
$("#" + idDiv).html(data);
nextStep = !$("#" + idHiddenErrores).val())
}
});
Omitting the attributes. Please help me.
You could use the jQuery wait method. I took an example from docs page to highlight how you'd do it:
$.when( $.ajax( "/request.php" ) ).done(function( response ) {
// response argument resolved from ajax requests
// process any work after ajax call finishes
}
A link to docs page:
http://api.jquery.com/jquery.when/
I'm doing this async: false for waiting and it works, but this is a bad design also I can't use a blockUI plugin.
Unless your wizard is better designed and supports async callbacks (e.g., promise-returning ones), async:false is your only choice.
Consider switching to a different wizard, and don't forget to file a bug for the plugin that you're currently using.
One hackish work-around is to do it before leaveStep. Perhaps on showStep:
var wizard_next_step;
$("#wizard").smartWizard({
onShowStep : function (obj, context) {
onLeaveStepFunction(obj, context, function(nextStep){
wizard_next_step = nextStep;
});
},
onLeaveStep : function () {
return wizard_next_step;
}
});
You'd also need to modify your onLeaveStepFunction to accept a callback:
function onLeaveStepCallback(obj, context, callback) {
nextStep = sendForm(callback);
}
And your ajax function should then be:
$.ajax({
url : path,
type : "POST",
async : false,
data : $("#" + idForm).serialize(),
success : function(data) {
$("#" + idDiv).html(data);
callback( !$("#" + idHiddenErrores).val()) );
}
});
Now, it looks like you're drawing into the wizard window with this:
$("#" + idDiv).html(data);
I'm entirely sure if this is the case. But if it is then you cannot do this here (obviously because it's onShowStep which would overwrite current content). If this is so you should pass the data in the callback:
success : function(data) {
callback( data , !$("#" + idHiddenErrores).val()) );
}
Write the wizard like this:
var wizard_next_step;
var wizard_data;
$("#wizard").smartWizard({
onShowStep : function (obj, context) {
onLeaveStepFunction(obj, context, function(data, nextStep){
wizard_data = data;
wizard_next_step = nextStep;
});
},
onLeaveStep : function (obj, context) {
$("#" + idDiv).html(wizard_data);
return wizard_next_step;
}
});
The key is to call all the asynchronous functions and get the data long before you call all your synchronous functions.
Note: I don't know smart-wizard at all and not a serious jQuery user. The answer above is based on my 2 minutes reading smart-wizard documentation on github and my understanding of javascript. You will definitely need to modify my examples to make it work.

AJAX call using IIFE? Can't seem to get .done to work the same as a regular function

I currently have an AJAX call out to a PHP file that works, that is the following:
//Load map from database
function getMap(){
return $.ajax({
url: "getMap.php",
type: "POST",
dataType: 'JSON',
});
};
getMap().done(function(r) {
if (r) {
loadedMap(JSON.parse(r.mapArray), JSON.parse(r.mapProperties)); //call loadedMap(r) if loading a map from DB
} else {
console.log("No data");
}
}).fail(function(x) {
console.log("error");
});
That works within a single javascript file that successfully passes r.mapArray and r.mapProperties to my main loadedMap function.
I'm trying to learn about the IIFE Javascript Module model, and split my work up into separate files.
So, I currently have main.js:
(function() {
// let's get our map
var gameMap = mapGen.getMap().done();
console.log(gameMap);
})();
and mapGen.js:
var mapGen = function() {
return {
getMap: function() {
return $.ajax({
url: "getMap.php",
type: "POST",
dataType: 'JSON',
});
}
};
}()
If I console.log(gameMap), I see the responseText JSON object with my data. I just can't seem to access it. console.log(gameMap.responseText) is undefined. as is gameMap.responseJSON (though I see both of them in the console).
Looking the code over it looks as the the separation of the files was not the issue and that looks to be implemented correctly. The issue is with how you are handling the AJAX request. The function mapGen.getMap() actually returns a jqXHR Object as opposed to the response that you are trying to access.
Just as you had in your previous file, you will need handle the response of your request.
(function() {
// let's get our map request
var gameMap = mapGen.getMap();
gameMap.done(function(r){ ... }).
fail(function(x){ ... });
})();
You will be able to access the response data you are looking for within the done() function.

What am i doing wrong with this dynamic query?

i've never used AJAX or JQuery before, but here's my attempt at dynamic loading(pulled from various examples here at stackoverflow)
this is the script i have in my view:(edited to comply with mayabelle's code.) doesn't throw either alert, and the breakpoint on DRequest never trips, but drequest produces results if called directly.
<script type="text/javascript">
$(document).ready(function () {
alert("testing123");
$response = DRequest;
alert("good at response");
$.ajax({
url: "request/drequest"
type: "GET",
dataType: "json",
success: function ($response) {
alert("I am an alert box2!");
// Do something with your response
var $tr = $('<tr>').append(
$('<td>').text($response.NeededByDate),
$('<td>').text($response.RequestedBy),
$('<td>').text($response.Username),
$('<td>').text($response.RequestedPCID),
$('<td>').text($response.RequestType_ID),
$('<td>').text($response.Division_ID),
$('<td>').text($response.ReqTypeIcon)
).appendTo('#requestTable');
console.log($tr.wrap('<p>').html());
}
});
setInterval(function () {
var url = '#';
$('body').load(url);
}, 300000);
});
</script>
is supposed to dynamically append one row at a time (until there are no more rows to add) from the DRequest JsonResult (this is producing results when called directly by way of the addressbar). this should reload the whole page every 5 minutes(300000 seconds).
the JsonResult looks like this
Public Function DRequest() As JsonResult
Dim Reqs = _db.dRequestGetAll
Return Json(Reqs, JsonRequestBehavior.AllowGet)
End Function
where "_db.dRequestGetAll" returns a collection of dRequest rows like so:
Public Function dRequestGetAll() As IEnumerable(Of DRequest)
Return From r In _PITcontext.Requests Where r.CompletedDate Is Nothing Select r
End Function
so. what did i miss?
EDIT: i replaced the javascript from the original post with the most current version since comments can't handle more than 600 characters.
Try like this:
$(document).ready(function () {
$.ajax({
url: url to your controller action,
type: "GET",
dataType: "json",
success: function (response) {
// Do something with your response
}
});
}
Also, in your code above you are calling your variable $response but then in your each loop you are trying to access response (no $ prefix).
I think you should be using $.map() instead of $.each(). It returns an array of your elements. Differences are discussed here.

Waiting for a function to return a value before firing jQuery Ajax request

I'm trying to fire an Ajax request with some data being returned by a function call and, as far as I can tell, the Ajax call isn't waiting for my function call to return.
I'm calling getSelectedMessages to get the values of a variable number of checkboxes before firing an Ajax request with an array of the values returned by getSelectedMessages.
getSelectedMessages looks like this:
var getSelectedMessages = function() {
var selected = [];
$('input:checkbox[name=multipleops]:checked').each(function() {
selected.push($(this).attr('value'));
});
return selected;
}
And the Ajax request that's invoking it looks like this:
$.ajax({
type: "POST",
url: "/api/messages/",
data: { ids: getSelectedMessages(), folder: folder },
cache: false,
success: function(){ location.reload() }
});
I've done a little bit of searching around and all I'm turning up are answers on how to return a value from a call and to it.
use
beforeSend attribute with ajax
try
var getSelectedMessages = function() {
var selected = [];
$('input:checkbox[name=multipleops]:checked').each(function() {
selected.push($(this).attr('value'));
});
return selected;
}
$.ajax({
type: "POST",
url: "/api/messages/",
beforeSend : function () { return jQuery.isEmptyObject(getSelectedMessages); }
data: { ids: getSelectedMessages(), folder: folder },
cache: false,
success: function(){ location.reload() }
});
Reference
beforeSend
isEmptyObject
Call getSelectedMessages() outside the ajax function of jquery (?)
The function is executed before the request is sent.
The real problem is that the getSelectedMessaged() returns an array.
This results in undefined=undefined after serialization in jQuery's internals.
And that gets ignored by the $.ajax(), so it looks like it's not sending in your vars but it's ignoring them because they're undefined.
If you concatenate a string with the values and make it a query string parameter yourself it should work.
I assume you want to send something like ?var[]=something&var[]=somethingelse to the server, so it ends up in PHP as an array?
Than you'll have to build up the string yourself in the getSelectedMessages function.
Hope it helps,
PM5544

Javascript function not returning properly?

function IsSwap()
{
var urlString = "<%= System.Web.VirtualPathUtility.ToAbsolute("~/mvc/Indications.cfc/GetModelType")%>";
var id =
{
id : GetGUIDValue()
}
$.ajax({
type: "POST",
url: urlString,
data: id,
success: function(data) {
if (data.toString() == 'SwapModel')
{
return true;
}
}
});
Expected result is true. I can alert right before the return so I know it's getting to that point fine. In another function, I tried to get my bool and use it like this:
var isSwap = IsSwap();
if (isSwap)
and it keeps saying isSwap is undefined. Why?
You are using ajax requests, which are asynchronous. You can't return value from an ajax request. Try this instead:
function IsSwap()
{
var urlString = "<%= System.Web.VirtualPathUtility.ToAbsolute("~/mvc/Indications.cfc/GetModelType")%>";
var id =
{
id : GetGUIDValue()
}
$.ajax({
type: "POST",
url: urlString,
data: id,
success: function(data) {
if (data.toString() == 'SwapModel')
{
ResultIsTrue(); // call another function.
}
}
});
After execution, instead of using this:
var isSwap = IsSwap();
if (isSwap){
// Do Somethinh
}
Try that:
IsSwap();
function ResultIsTrue(){
// Do Same Thing
}
You can't return from an ajax call like that.
Essentially what you're doing is returning true from the inner function.
You should just call whatever code you need in the success method as that's the only time you can guarantee that the ajax call has completed.
The AJAX request is asynchronous, meaning that IsSwap will return before the response to the AJAX request.
Whatever you need to do based on isSwap, you should do in the success handler of your AJAX request.
UPDATE: This last paragraph is incorrect about it working, but worth noting about synchronous not being recommended:
Alternatively, you could make the AJAX request synchronous (by adding async:false to the AJAX options) and keep it how you have it - however I wouldn't recommend this as your browser will 'freeze' whilst it waits for the response.
Check this line:
var urlString = "<%= System.Web.VirtualPathUtility.ToAbsolute("~/mvc/Indications.cfc/GetModelType")%>";
Try using single quotes like so:
var urlString = '<%= System.Web.VirtualPathUtility.ToAbsolute("~/mvc/Indications.cfc/GetModelType")%>';
Your double quotes inside double quotes is most likely your problem.

Categories