Still Having Problems Returning Value Through Function - javascript

I'm having serious problems with the function below:
function requestUploadedSearch()
{
var cookie = JSON.parse(readCookie("user_search_cookie"));
$.ajax({
dataType: "script",
async: false,
data: {
context: "search-get",
code: removeNull(cookie, cookie !== null, "code")
},
success: function(data)
{
var keywords = search_return["keywords"];
return keywords; // here is the damn problem.
}
});
}
Seams that simply nothing comes out of the function except for the undefined value and no errors are shown in the debugger.
And I'm seriously almost throwing my laptop on the wall.
If anyone could help me doing this, please answer!
Thanks in advance.

1st off: Where is the search_return variable? Why are you ignoring data?
I have a feeling this is what you want to do:
function requestUploadedSearch()
{
var cookie = JSON.parse(readCookie("user_search_cookie"));
var keywords;
$.ajax({
dataType: "json",
async: false,
data: {
context: "search-get",
code: removeNull(cookie, cookie !== null, "code")
},
success: function(data)
{
keywords = data["keywords"];
}
});
return keywords;
}

The issue is that since the Ajax call will complete at an arbitrary time in the future, you cannot simply return a value from its success handler.
One issue is that you're not actually doing anything with the data returned by the server, which seems puzzling.
The nutshell version is that you need to implement the functionality as part of the success callback. That can be done in-line, or you can create the callback function outside of the Ajax call itself and use it as the value for the success property:
function onSuccess(data) {
// Do something with the data here
}
...
$.ajax({ // etc.
success: onSuccess
};
You may also use jQuery's $.when function.

The problem is the scope you're trying to return your keywords from. The success function is called by jQuery, and you don't have any control over what jQuery does with that return value. You could do return $.ajax(... but you wouldn't get what you expect, since according to the documentation: "As of jQuery 1.5, the $.ajax() method returns the jqXHR object, which is a superset of the XMLHTTPRequest object" (http://api.jquery.com/Types/#jqXHR).
What you should do instead is set up a callback function like:
function doSomethingWithKeywords(keywords) {
// do stuff
};
and in the success function call that function:
doSomethingWithKeywords(keywords);
EDIT: Hogan's is a good solution, since your call isn't asynchronous.

The problem you are having is the return you are passing is not the return of the function -- it is the return of the event of success. Often closures (implied passing of a local variable to a function) are used to solve this problem in JavaScript.
NB I still don't think your function will work because I don't see where search_return["keywords"] is defined. But at least you won't have to worry about the closure issue. Once your success function is correct the main function will return it.
Like this:
function requestUploadedSearch()
{
var cookie = JSON.parse(readCookie("user_search_cookie"));
var returnClosure;
$.ajax({
dataType: "script",
async: false,
data: {
context: "search-get",
code: removeNull(cookie, cookie !== null, "code")
},
success: function(data)
{
// returnClosure = data["keywords"];
returnClosure = search_return["keywords"];
}
});
return returnClosure;
}

Related

access class function inside ajax success [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 7 years ago.
im trying to assign a variable inside the ajax success callback.
i know that in order to assign the value i need to use a call back function. but i want that function to be inside the class. is it possible to implement something like this?
function callMgmt_class() {
this.room_id = 'Error';
this.assignRoomVar = function(room_id) {
alert();
this.room_id = room_id;
}
this.getRoomID = function() {
$.ajax({
url: "/get_room_id.php",
dataType: "json",
success: function(data) {
this.assignRoomVar(data.room_id);
}
})
}
}
is there some way to use bind?
i tried:
success: function(data) {
(function() { this.assignRoomVar(data.room_id); }).bind(this);
}
so i dont get any errors but the function does not seem to be called.
Your use of this is flawed. 'this' inside the callback will use the context of the callback whereas what you need is the context of your class. You can do that by caching the 'this' context in a variable and using it instead.
this.getRoomID = function() {
var me = this;
$.ajax({
url: "/get_room_id.php",
dataType: "json",
success: function(data) {
me.assignRoomVar(data.room_id);
}
})
}
this is not the this you are looking for.
The this keyword is tricky and takes on different references depending on the context. When you are accessing this in the ajax success function, it is not referring to the callMgmt_class object anymore (I think it would reference the ajax function).
The best way to get around this is to assign this to another variable when you are sure of its value. So at the beggining of your function is the best bet
this.getRoomID = function() {
var that= this;
//Now use that instead of this when you want to refer to the callMgmt_class object
$.ajax({
url: "/get_room_id.php",
dataType: "json",
success: function(data) {
that.assignRoomVar(data.room_id);
}
})
}
Addition:
I think using bind or apply are other alternatives, but I am not very familiar, so I'll leave that for someone else to answer.

closures with ajax, using variable from ajax

I am having problems using variables inside functions. So I have code:
functions.js:
function foo (callback){
$.ajax({
type:"POST",
url:"ajax/companyInfo.php",
data: dataString,
success: callback
});//end ajax
alert (dada);
}
function mycallback (result){
array=result.split('/');
alert(dada);
}
invoice.php:
var array = [];
var dada="";
$('#next1').on('click', function(){
dataString='company= '+$(this).closest('.inside').find('select').val(); // this is just for ajax
resizeall($(this), 200, 100); //this is function that works and has no problem
foo(mycallback);
console.log(array);
});//end on click function
It says:
Uncaught ReferenceError: dada is not defined functions.js:41
Uncaught ReferenceError: dada is not defined functions.js:46
I think it's might be related to closures isn't it. What is going wrong?
Kind of hard to debug since I can't see all of the invoice.php or functions.js
The line numbers you report (41 and 46) indicate that there is more to functions.js then
what you pasted.
But I'll give a hack you could try
invoice.php
var array = [];
window.dada="";
$('#next1').on('click', function(){
dataString='company= '+$(this).closest('.inside').find('select').val(); // this is just for ajax
resizeall($(this), 200, 100); //this is function that works and has no problem
foo(mycallback);
console.log(array);
});//end on click function
functions.js
function foo (callback){
$.ajax({
type:"POST",
url:"ajax/companyInfo.php",
data: dataString,
success: callback
});//end ajax
alert (window.dada);
}
function mycallback (result){
array=result.split('/');
alert(window.dada);
}
Here is what your setup should look like.
function getCompanyInfo(companyName) {
return $.post("ajax/companyInfo.php", {
company: companyName
}).then(function (rawData) {
return rawData.split("/");
});
}
$('#next1').on('click', function() {
var companyName = $(this).closest('.inside').find('select').val();
resizeall($(this), 200, 100);
getCompanyInfo(companyName).done(function (array) {
console.log(array);
// everything else you want to do with the array goes here
});
});
Read up on jQuery Deferreds to find out what .then() and .done() do.
Final tip: If you want to update data on the server, use a POST request. If you want to fetch information from the server, use a GET request. The .post() in my code above is there because you used it in your code. It's semantically wrong and you really should change it to .get().

Return value of a callback function in jQuery?

I have this code:
function dialogTexts(message) {
var langText = $.ajax({
type: 'GET',
url: '/index.php/main/dialogtexts',
dataType: 'json'
});
langText.done(function(data) {
message(data);
});
langText.fail(function(ts) {
alert(ts.responseText);
});
}
dialogTexts(function(text) {
alert(text.delete);
});
I'm using a callback to alert the string text.delete (in above code), but I want to do something like:
dialogTexts(function(text) {
return text;
});
var deleteConfirmationDialogText = dialogTexts.delete;
alert(deleteConfirmationDialogText); //deleteConfirmationDialogText is undefined
dialogTexts is a function and it does not have a property .delete. That's why dialogTexts.delete is undefined when you try to use it. You simply can't use the kind of shortcut you're trying to do.
Also, the return statement in here:
dialogTexts(function(text) {
return text;
});
is doing nothing. It's just returning to the caller of that callback which is inside of dialogTexts() and that caller is not doing anything with the return value so return text is doing nothing.
If you want to alert the text, you will have to do what you first had:
dialogTexts(function(text) {
alert(text.delete);
});
That is the only real way to do it and this is a consequence of how asynchronous programming works with AJAX calls. There are some other techniques for handling callbacks (such as promises), but they all require you to process the asynchronously returned data in a callback function. That's just the nature of asynchronous programming.

Avoiding async: false; in jQuery AJAX within a function

Here's some pseudo code that I'm working with (and where'd I'd typically use async: false;):
function getData(){
var obj = {};
if(!settings.data){
$.ajax({
url: '/someendpoint',
async: false,
success: function(data){
obj = data;
}
});
} else {
obj = settings.data;
}
return obj;
}
So we have a function that returns an object. Now if we already have some data, we just assign this data, but if we don't, we need to request the data from the server. A time to use async: false? Because we need to halt execution as to grab the data before we return the obj?
I deal with this concept time and time again, resorting to async: false most times. Can someone outline a better approach please?
Embrace the asynchronous nature of the web. Granted, it's paradigm shift, but so was multi-threading back in the day and in my opinion the way it's handled now in jQuery with Deferred objects makes it preferable over multi-threading. It's the reason why Node.js is becoming so popular.
Don't just use callback functions as you might read on the web or in other answers. Learn about Deferred and Promise objects, and instead of returning the data, return a promise that you can use to attach behavior to when that promise is 'resolved'.
function getData(){
var obj;
if(!settings.data){
obj = $.get('/someendpoint');
} else {
obj = $.when(settings.data);
}
return obj;
}
Then, the caller can use this data the moment it becomes available, as such:
var promise = getData();
promise.done(function (data) {
// Do something with the data.
});
It will feel awkward at first, because you're no longer returning data but instead a 'promise' to that data, but after a while you'll just 'get it'. Trust me.
Use a simple callback mechanism
function getData(callback){
var obj = {};
if(!settings.data){
$.ajax({
url: '/someendpoint',
success: function(data){
callback(data)
}
});
} else {
callback(settings.data)
}
}
getData(function(data){
//do things which depends on data
})

Ajax jquery success scope

I have this ajax call to a doop.php.
function doop(){
var old = $(this).siblings('.old').html();
var new = $(this).siblings('.new').val();
$.ajax({
url: 'doop.php',
type: 'POST',
data: 'before=' + old + '&after=' + new,
success: function(resp) {
if(resp == 1) {
$(this).siblings('.old').html(new);
}
}
});
return false;
}
My problem is that the $(this).siblings('.old').html(new); line isn't doing what it's supposed to do.
thanks..
all helpful comments/answers are voted up.
Update: it appears that half of the problem was the scope (thanks for the answers that helped me clarify that), but the other half is that I'm trying to use ajax in a synchronous manner. I've created a new post
You should use the context setting as in http://api.jquery.com/jQuery.ajax/
function doop(){
var old = $(this).siblings('.old').html();
var newValue = $(this).siblings('.new').val();
$.ajax({
url: 'doop.php',
type: 'POST',
context: this,
data: 'before=' + old + '&after=' + newValue,
success: function(resp) {
if(resp == 1) {
$(this).siblings('.old').html(newValue);
}
}
});
return false;
}
"this" will be transfer to the success scope and will act as expected.
First of all new is a reserved word. You need to rename that variable.
To answer your question, Yes, you need to save this in a variable outside the success callback, and reference it inside your success handler code:
var that = this;
$.ajax({
// ...
success: function(resp) {
if(resp == 1) {
$(that).siblings('.old').html($new);
}
}
})
This is called a closure.
this is bound to the object to which the executing function was applied. That could be some AJAX response object, or the global object (window), or something else (depending on the implementation of $.ajax.
Do I need to capture $(this) into a variable before entering the $.ajax call, and then pass it as a parameter to the $.ajax call? or do I need to pass it to the anonymous success function? If that's going to solve the problem, where do I pass it to the $.ajax?
You do indeed need a way to capture the value of this before defining the success function. Creating a closure is the way to do this. You need to define a separate variable (e.g. self):
function doop() {
var old = $(this).siblings('.old').html();
var new = $(this).siblings('.new').val();
var self = this;
$.ajax({
url: 'doop.php',
type: 'POST',
data: 'before=' + old + '&after=' + new,
success: function(resp) {
if(resp == 1) {
$(self).siblings('.old').html(new);
}
}
});
return false;
}
The success function will retain the value of self when invoked, and should behave as you expected.

Categories

Resources