This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I have below code in angular service
this.get = function(url,qParams)
{
var webresponse = new Object();
$http.get(url+qParams)
.success(function(result){
webresponse.data = result;
webresponse.state = 1;
})
.error(function(result){
webresponse.data = result;
webresponse.state = 0;
});
console.log('webresponse :' + webresponse.data);
return webresponse;
}
In console log shows webresponse.data as undefined. Please help me to understand why. Is it scope issue?
just to let you know result is JSON array and in console log it shows JSON array as expected with all elements in it.
Your $http.get() is an async call and your console.log is in synchronous fashion, so console.log initiated first then your $http.
Method calls in $http are asynchronous: The result will not be necessarily available after the function .get() returns. Please check again the docs for $http.
Data in webresponse will not be available (i.e. your variable is not set yet to anything other than the plain object) but only when the $http.get request fetches the data from the server. Such moments are the .success trigger, the .error trigger, and also a trigger you did not use (and perhaps don't need) called .finally (works regardless whether .success and .error have been triggered).
You cannot access the webresponse outside those callbacks since they are the only guaranteed moments where such values will be available. Even more! You cannot RETURN such value from the function. Since the behavior is asynchronous you will have to return something in the same asynchronous way. Please check the $q service to learn how to do it. It is a long topic and you lack the basics on this topic so I will give you some guidelines:
$http is an asynchronous service. Their calls (e.g. .get() return something called a promise. Your function should return a promise (either the same or other).
The actual result itself (i.e. the result you want) will not be available as you intend: The function's invoker must attend the promise you return, specify a callback for it, and attend it in the callback.
More information: You need a deeper knowledge of $http and $q services. They are pretty well documented in the official docs.
you function is an synchronous call.
this.get = function(url,qParams)
{
var webresponse = new Object();
$http.get(url+qParams)
.success(function(result){
webresponse.data = result;
webresponse.state = 1;
console.log('webresponse :' + webresponse.data);
//triger any function #here when its success
})
.error(function(result){
webresponse.data = result;
webresponse.state = 0;
console.log('webresponse :' + webresponse.data);
//triger any function #here when its fail
});
}
Your this.get() function can't return result immediately.
As you know, the $http module use ajax, (AJAX: Asynchronous Javascript and Xml )
so you have to wait for the asynchronous response in your success or error callback function.
If you want to return the response, please consider promise pattern.
Related
var final;
final = $http.get('http://localhost:9000/therapist_data',config)
.success(function(response) {
console.log("I got the data I requested");
var resdata = response;
console.log(resdata);
return resdata;
});
console.log(final);
I am trying to return response data and store it into final variable instead I am getting the promise object.
How do I return actual data?
I'll try to develop Cyril answer based on your code :
var final;
final = $http.get('http://localhost:9000/therapist_data',config)
.success(function(response) {
console.log("I got the data I requested");
var resdata = response;
console.log(resdata);
return resdata;
});
console.log(final);
Here is the order of execution :
var final
$http.get('http://localhost:9000/therapist_data',config)
.success(); : this will trigger the request and register the function in success as a callback when server will have respond to your request
console.log(final); -> so still undefined. It does NOT WAIT for the response.
some times later ... your function in the success is called.
This is the very basis of callbacks and asynchonous processing, you don't know when it will be executed, or at least, it will often be executed after all the other code. In angularJS there is no way of doing a synchronous request. You must move you code in the success function.
As long as you are making a network call, your data will return back asynchronously, it is the nature of it, you can't fight it.
var wrongFinal; // <-- nope, final will never get into that scope
$http.get('http://localhost:9000/therapist_data',config)
.success(function(response) {
console.log("I got the data I requested");
var goodFinal = reponse; // <-- yes, here, the data lived
// do something with the data here
});
console.log(wrongFinal); // nop, wrong scope, no sense, data doesn't live here
Soooooo, the answer is a question:
What do you want to do with your data?
It depends on the destination. Are you going to make anoher network call? Do you want to update the view? Do you want to call a 3rd party library?
You need to understand and to embrace the nature of asynchronous in JavaScript.
$http.get will always return a promise.
If you'd like to get the promise value you should do it inside the success callback, like this:
var final;
$http.get('someUrl').success(function(response) {
final = response;
});
No need for resData, will only cause a promise chain, something you don't require in this case.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
Like a person asked here (but his solutions as to call a nother function) https://stackoverflow.com/a/10796326/315200 ...I would like to know if its possible to have a function which doesn't call a second function on response of an async request, but simply return when the async request responses.
Something like this maybe:
function callToFacebook() {
var fbResponse;
FB.api('/me', function (response) {
fbResponse = response;
});
return fbResponse; //Will return undefined because CallToFacebook is async
}
Isn't that possible some way, without calling another function??
What I'm trying to achieve is to have one function I can call with some parameters, which will return the response object from a async webservice, like FB.
In short, no. You cannot have an asynchronous function return a meaningful value synchronously, because that value does not exist at that time (as it is built asynchronously in the background).
You can, however, return a Promise object, representing the "potential return value" of the asynchronous operation, and bind a function to that object using done() or similar. That way, your function gets return semantics (instead of having to chain the control flow into a callback), and remains asynchronous.
No, it's not possible.
You can't return value that is returned from async operation.
Think about it, you tell 10 people to have one mile running contest, they start now, will finish in one minute +-, but you want to know the answer now, it's not possible unless you're cheating...
I'm aware that Angular can handle promises from within controllers. For example:
function MyCtrl($scope) {
$scope.myvar = getDeferredPromise();
}
The main angular digest loop handles this gracefully, assigning whatever value the deferred function finally returns later to myvar.
However, although the $http.get() method returns a promise, I cannot get it to work in this way. For example:
function MyCtrl($scope, $http) {
$scope.myvar = $http.get('/url');
}
The 'promise' the get method returns has a success method which takes a function that is assigned the data that one would wish to assign to myvar.
However, it also has a then method - but that is given the entire response object - not just that data part! This is what seems to end up getting assigned to myvar!
This fiddle may help: http://jsfiddle.net/QKnNC/1/
Am I doing something wrong here? Or is this somehow 'by design'?
ng.$http
The $http service is a function which takes a single argument — a
configuration object — that is used to generate an HTTP request and
returns a promise with two $http specific methods: success and error.
$http returns a promise, so you need to chain then to get the data.
IPService.getV1().then(function (response) {
console.log(response)
$scope.value1 = response.data;
});
then is the general promise function, that takes a success and error callback and you get the resolved value, whatever it may be. success and error are $http specific, and are aliases for then with one exception: they set a bunch of useful arguments rather than just the data. See the source.
It is by design. Your getV2() method is what you want. Since you are using GET, you could save the result of your promise and return that on subsequent calls to getV2():
var v2promise, v2data;
return {
getV2: function() {
if(!v2promise) {
v2promise = $http.get('http://ip.jsontest.com/').then(
function(response) {
v2data = response.data;
return v2data;
});
}
return v2promise;
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to return the response from an AJAX call from a function?
I have tried debugging in Google Chrome's Developer Console but in any way I cant get the result I want. I want to create a javascript function that will return a value from an external file through AJAX. I have tried this script:
var site = {
token: function(){
$.get('auth.php',function(data){
return data;
});
}
};
...when I call the site.token() function it should return the fetched contents from auth.php. But it just doesn't. It is always undefined. I also tried this:
var site = {
token: function(){
var token = null;
$.get('auth.php',function(data){
token = data;
});
return token;
}
};
But its still the same. I also find a work around by doing this:
var token = $.get('auth.php',function(data){
return data;
});
token.responseText;
With that codes, I can now get my expected result. But when I put it already in a function:
var site = {
token: function(){
var token = $.get('auth.php',function(data){
return data;
});
return token.responseText;
}
};
...it fails again.
*P.S.: I don't know maybe I'm just really stressed in programming and why I can't do it right. -_-"
$.post() is short-hand for $.ajax(), and both are asynchronous (unless you do very bad things). You don't want to freeze the browser's GUI thread for the duration of the request to the php page. Thus site.token() can not reply with the data.
However, $.ajax() does return a promise (see http://www.erichynds.com/jquery/using-deferreds-in-jquery/ and how does jquery's promise method really work?). In essence, it says "I promise I'll call you back when I'm done." So, you can construct the class like this:
var site = {
token: function(){
var promise = $.get('auth.php',function(data){
return data;
});
return promise;
}
};
and call it like this:
var promise = site.token();
promise.done(function (data) {
alert('got the data');
console.dir(data);
});
If this were possible, then the function idea could be discarded, and the syntax could just be:
var data = $.post("url");
It isn't possible however, because AJAX is asynchronous. It takes a while before the response is received. When this is the case, your function is called. That's the idea of passing a function.
There is no way to make this synchronous so as to use return. You can use $.ajax with async: false but it's going to be deprecated. The best you can do is return $.post(...) and then use .done(...) on the result to use the response.
Ajax calls are asynchronous, thus you use your data before it is fetched. Consider using deffered object.
http://api.jquery.com/category/deferred-object/
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
How would I, using $.post() in a function, force the return on the post callback?
Example:
function myFunction(){
$.post(postURL,mydata,function(data){
return data;
});
}
I have tried playing around with it using .done() and .queue() however neither has worked for me.
I understand there is a fundamental flaw in my example; with that said, how can I achieve my desired functionality?
This is impossible. $.Ajax calls will always return immediately. You need to deal with the return when it is called through a callback (possibly several seconds later). Javascript never blocks for a given call. It may help to think of your code like this:
//This entirely unrelated function will get called when the Ajax request completes
var whenItsDone = function(data) {
console.log("Got data " + data); //use the data to manipulate the page or other variables
return data; //the return here won't be utilized
}
function myFunction(){
$.post(postURL, mydata, whenItsDone);
}
If you're interested more on the benefits (and drawbacks) of Javascript's no-blocking, only callbacks: this Node.js presentation discusses its merits in excruciating detail.
function myFunction(){
var deferred = new $.Deferred();
var request = $.ajax({
url: postURL,
data: mydata
});
// These can simply be chained to the previous line: $.ajax().done().fail()
request.done(function(data){ deferred.resolve(data) });
request.fail(function(){ deferred.reject.apply(deferred, arguments) });
// Return a Promise which we'll resolve after we get the async AJAX response.
return deferred.promise();
}