Always returning function returns undefined [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
There is this small function that should logically returns always, but I am getting undefined :-
function hasAccess() {
var dataObj = {
"id" : $scope.groupId
};
$http.post('http://vlinux:9099/GetItems', dataObj).then(
function(response) {
var result = response.data.result;
if(result.includes($scope.screenId)) {
return "ok";
} else {
return "nok";
}
});
}
I started getting downvotes, so wuickly adding, I debugged it and saw http call is bringing expected response and flow is jumping to the right if/else block. Problem is when I am calling this function in a variable its storing undefined.
The call is simple too :-
var allow = hasAccess();

$http.post is not synchronous, but asynchronous.
Thus, all that you have after $http.post is a promise, not the boolean you are expecting.
The documentation show wells how to provide a "callback" to your function, in case of success as well as failure :
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
// for example : manageWHenOk
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
// for example : manageWHenKO
});

Your function return a result only if the request is fine. If there is an error your function do nothing! I suggest you to add a catch function.
function hasAccess() {
var dataObj = {
"id" : $scope.groupId
};
$http.post('http://vlinux:9099/GetItems', dataObj).then(
function(response) {
var result = response.data.result;
if(result.includes($scope.screenId)) {
return "ok";
} else {
return "nok";
}
}).catch(function (error) {
// do something
});
}
If you still have undefined it means that your template is loaded before to obtain the response. In order to resolve that you can do the request in the resolve method of the $stateProvider.

Related

returning data nested inside ajax callback [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
im trying to get data from an ajax function to my actual app but i cant seem to pass the data outside of the function, ive read other questions and tried their recommendation but it doesnt seem to be working because its not waiting for ajax to finish loading before trying to return the data,
im trying to return uid so that i can do something like
user = getUserID('test');
instead of
getUserID('user', function(id){ console.log(id); });
because i am assigning the returned data to a variable
getUserID = function(user, cb) {
var uid;
$.ajax({
type: "GET",
url: "/user_comment.php",
data: {
user: user
},
success: function(result) {
if (result) {
uid = /name="recipient_id" value="(.*)"/g.exec(result)[1];
console.log('1 ' + uid);
if(cb) {
try {
cb(null, uid);
} catch(e) { cb(e); }
}
} else {
console.log("ERROR!! - No data returned !")
}
}
});
console.log('2 ' + uid);
return uid;
},
all it does right now is
2 undefined
1 5511194
2 undefined
1 1462473
2 undefined
1 5469682
so it is not setting the variable
Your code is returning the value of "uid" before any value is applied to it. You can see that your variable is set in "success" callback. This means that this callback will be called only after the asynchronous call is done. Your "getUserID" function will end AND the "return" statement will be executed BEFORE the callback. Play with your code in the debugger, you'll see what's actually going on. So what you should do is use the returned value in the "success" callback instead of the returned value from "getUserID". Like this:
getUserID('test', function(uid){
... do your stuff here => uid is defined and has the value you're looking for
});
But just don't try to do something like:
var uid = getUserID('test');
... things and stuff

Scope not updating after $http AJAX call [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 6 years ago.
The following code is in my controller - when I reach the console.log() line, nothing is printed out. The AJAX call returns a valid array. I tried using $scope.$apply but I got an process already in progress error, I'm assuming because using $http automatically starts the digest cycle:
var mmyApp = angular.module('myApp',['ui.bootstrap']).controller('TasksController', TasksController);
function TasksController($scope, $http) {
$scope.transactions = [];
$http.get('transactions').then(function (response) {
$scope.transactions = response.data;
}, function (error) {
throw error;
});
console.log($scope.transactions);
}
$http.get is asynchronous. When you call your console.log, your GET request didn't return yet. You can move it inside the handle body to see that it works:
$http.get('transactions').then(function (response) {
$scope.transactions = response.data;
console.log($scope.transactions);
}, function (error) {
throw error;
});
You should know that AJAX calls made with $http in AngularJS are asynchronous, that is, they do not run in sequence with the rest of the code, unless you set it that way.
Therefore when the console.log is executed, the request still has not finished processing. The correct thing is that you run console.log after performing the assignment of the variable in the AJAX call, in this way:
var mmyApp = angular.module('myApp',['ui.bootstrap']).controller('TasksController', TasksController);
function TasksController($scope, $http) {
$scope.transactions = [];
$http.get('transactions').then(function (response) {
$scope.transactions = response.data;
console.log($scope.transactions);
}, function (error) {
throw error;
});
}

Ajax request return the response after js check [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
Instead of all sorry for the misleading title, I'll try to explain better. My customer fill a form with personal information, this information are validate from an ajax request that calls a php function. This php function return SUCCESS if the validation it's successfull, instead return the exception. Now when the user click on the next button the javascript code call this function:
if(!FrontendBook.validateCustomerForm())
{
return; //FAIL
} else
{
//do stuff
}
the validateCustomerForm function contain this:
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_save_customer';
var postData = { 'customer': JSON.stringify(GlobalVariables.customerData) };
$.post(postUrl, postData, function(response)
{
if(response.status == "SUCCESS")
{
return true;
}
else
{
return false;
}
}, 'json');
Now in the browser console I see correctly the reponse content, and if I put an alert inside response.status == "SUCCESS" the alert is displayed correctly.
Initially I don't understood why in the if(!FrontendBook.validateCustomerForm())
the code enter in the return statement, so in the fail validation. But I ran this test:
Print the result of FrontendBook.validateCustomerForm in console.log()
Check in which statement the condition was
In console.log I get undefined and of course the condition statement fall into the return; //FAIL.
Maybe this is a problem of time? Someone could explain why the function return undefined when I return true or false in the specific contest?
You seem to be misunderstanding promises and the asynchronous nature of this function call. Observe the following way we can accomplish this...
// declaration
function validateCustomerForm() {
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_save_customer';
var postData = { 'customer': JSON.stringify(GlobalVariables.customerData) };
return $.post(postUrl, postData); // return promise object
}
// usage
validateCustomerForm().done(function(response) { // resolve promise
if(response.status == "SUCCESS")
/*...*/
});
Check out the jQuery deferred api for more information - since we are returning a promise from your function, then later resolving it.
JSFiddle Link - simplified demo

Javascript - Pass callback value to calling variable [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I have a function and a variable....
var imageURLs = retrieveRemoteImages(vinUrls)
if imageURLs !== undefined) {
// do something
}
function retrieveRemoteImages(urls) {
var imageURls = [];
processSpinnerActivity(START_IMAGES_IMPORT);
importImagesforSlideShow(REMOTE_IMAGES_URL, urls, function (images) {
if (images !== undefined) {
imageURls = images;
return imageURls;
}
})
return imageURls;
}
This does as intended ....
function importImagesforSlideShow(imagePath, urls, call_back) {
var functionName = 'importImagesforSlideShow'
$.ajax({
type: "POST",
url: LOCAL_PROCESSING_MODULE,
data: {data: [imagePath, urls, IMAGE_EXTENSION_QUALIFIER], functionid: functionName},
dataType:"json",
success: function (res) {
processSpinnerActivity(IMPORT_IMAGES_SUCCESS);
call_back(res);
},
error: function (err) {
processSpinnerActivity(IMPORT_IMAGES_ERROR);
console.log(err.message);
}
});
}
The callback works fine, but I am not able to pass the eventual value to imageURLs and I need to, as the next step cannot occur until it has a value.
Any ideas?
Thanks!
This is not a duplicate question, I have no issues with my AJAX returning the async value*
It's not possible like that, you are executing a piece of async code. So your code keeps running while their isn't any data yet. You have to process your data in a callback, for example like this:
function retrieveRemoteImages(urls, callback) {
processSpinnerActivity(START_IMAGES_IMPORT);
importImagesforSlideShow(REMOTE_IMAGES_URL, urls, callback);
}
retrieveRemoteImages(vinUrls, function(imageURLS) {
//do your stuff
});

Function inside jquery returns undefined [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
The function I called inside jquery returns undefined. I checked the function and it returns correct data when I firebugged it.
function addToPlaylist(component_type,add_to_pl_value,pl_list_no)
{
add_to_pl_value_split = add_to_pl_value.split(":");
$.ajax({
type: "POST",
url: "ds/index.php/playlist/check_folder",
data: "component_type="+component_type+"&value="+add_to_pl_value_split[1],
success: function(msg)
{
if(msg == 'not_folder')
{
if(component_type == 'video')
{
rendered_item = render_list_item_video(add_to_pl_value_split[0],add_to_pl_value_split[1],pl_list_no)
}
else if(component_type == 'image')
{
rendered_item = render_list_item_image(add_to_pl_value_split[0],add_to_pl_value_split[1],pl_list_no)
}
}
else
{
//List files from folder
folder_name = add_to_pl_value_split[1].replace(' ','-');
var x = msg; // json
eval('var file='+x);
var rendered_item;
for ( var i in file )
{
//console.log(file[i]);
if(component_type == 'video')
{
rendered_item = render_list_item_video(folder_name+'-'+i,file[i],pl_list_no) + rendered_item;
}
if(component_type == 'image')
{
rendered_item = render_list_item_image(folder_name+'-'+i,file[i],pl_list_no) + rendered_item;
}
}
}
$("#files").html(filebrowser_list); //Reload Playlist
console.log(rendered_item);
return rendered_item;
},
error: function()
{
alert("An error occured while updating. Try again in a while");
}
})
}
$('document').ready(function()
{
addToPlaylist($('#component_type').val(),ui_item,0); //This one returns undefined
});
The function addToPlaylist doesn't return anything. It makes an asynchronous request, which eventually executes a callback function, which returns something. The original addToPlaylist function is long done and returned by the time this happens though, and the callback function returns to nobody.
I.e. the success: function(msg) { } code executes in a different context and at a later time than the surrounding addToPlaylist function.
Try this to see it in action:
function addToPlaylist() {
$.ajax({
...
success : function () {
alert('second'); // comes after 'first'
return null; // returns to nobody in particular
}
});
alert('first'); // comes before 'second'
return 'something'; // can only return here to caller
}
You're making your request via AJAX, which by definition is asynchronous. That means you're returning from the function before the AJAX request completes. In fact, your return statement is meaningless as it returns from the callback function, not your addToPlaylist function.
You have a couple of choices. The first one is better.
First, you can work with the asynchronous nature of the AJAX request and pass a callback into your addToPlaylist method (much like you're passing in the anonymous callback to the ajax function) and have the AJAX callback, call that function instead of doing the return. That way your request completes asynchronously and doesn't lock up your browser while it's going on.
function addToPlaylist(component_type, add_to_pl_value, pl_list_no, cb )
{
...yada yada yada...
$.ajax({
...
success: function(data) {
...
if (cb) {
cb.apply(this, rendered_item );
}
}
});
}
Second, you can add the option aSync: false to the ajax call. This will force the AJAX call to run synchronously (essentially it just loops until the call returns then calls your callback). If you do that, you need to capture a local variable in your addToPlaylist function inside the callback and assign the value(s) to it from the callback. At the end of the addToPlaylist function, return this variable as the result.
function addToPlaylist(component_type, add_to_pl_value, pl_list_no )
{
...yada yada yada...
var result = null;
$.ajax({
aSync: false,
...
success: function(data) {
...
result = rendered_item;
}
});
return rendered_item;
}
I agree with deceze. What you need to do is perform the necessary action(s) for rendered_item in the success function rather than relying on getting something back from addToPlayList().

Categories