Reputation: 797
when I define the factory method like this
dataFactory.all = function() {
return 'test01';
}
and call it in controller like this
console.log(Data.all());
I can get test01
printed. However, when I add some logic in factory all()
method like this
dataFactory.all = function() {
$http
.get('/api/hey')
.success(function(data) {
$http
.get('/api/hi')
.success(function(data) {
return 'test'; // 'test' can not be printed, and console show 'undefined'
});
});
//return 'test01'; //can be printed;
};
then the 'test' can not be printed via the controller. Because I put the return
statement in the callback?
Please let me know what I am doing wrong?
Thanks.
Upvotes: 0
Views: 1230
Reputation: 702
Take a look at angular's $q
(docs). With $q you can create a deferred object and return it's promise from your factory method.
That should allow you to retrieve the resulting data from your $http call in a then
callback since your factory will be returning a promise:
dataFactory.all = function() {
// create deferred object
var deferred = $q.defer();
$http.get('/api/hey')
.success(function(data) {
$http.get('/api/hi')
.success(function(data) {
// resolve the promise with your http request result, this value will
// be the result passed to your factory method's
// `then` callback
deferred.resolve(data);
}
}
return deferred.promise;
}
update
@HankScorpio is right, this could be simplified greatly by returning the $http.get
function calls because they return promises themselves:
dataFactory.all = function() {
return $http.get('/api/hey').success(function(response) {
return $http.get('/api/hi');
});
}
Working update is here: http://plnkr.co/edit/wtMnOjjUnKV5x8CQrbIm?p=preview
Upvotes: 1
Reputation: 6205
Because you are not returning any value in the scope of the all
method and also you need to pay attention that $http
return a promise.
So.. your method could be somemething like this:
dataFactory.all = function(jobname) {
return $http.get('/api/jobs/' + jobname + '/realtimeData').success(function(realtime) {
return $http.get('/api/jobs/' + jobname + '/nonliveData').success(function(nonlive) {
return 'test';
});
});
};
Or.. to void nested promises you could refactor a bit your code using Flattened Promise Chains :
dataFactory.all = function(jobname) {
return $http.get('/api/jobs/' + jobname + '/realtimeData').then(function(realtime) {
// do something with realtime
return $http.get('/api/jobs/' + jobname + '/nonliveData');
}).then(function(nonlive){
return 'test';
});
};
And because your method all
now return a promise, you need to:
dataFactory.all(jobname).then(function(nonlive){
console.log(nonlive); // should return test!
});
Upvotes: 1
Reputation: 1496
I don't think its because you've built it incorrectly, but it looks as though your factory ($http
) method is running asynchronously. Try returning a promise like so:
datafactory.all = function() {
return new Promise(resolve, reject){
// Your logic here...
$http
.get('/api/hey')
.success(function(data) {
resolve(data);
})
.fail(function(err){
reject(err);
});
}
};
Then you can consume your factory method like so:
datafactory.all().then(function(result){
// Success!
}, function(err){
// Error!
});
Upvotes: 1
Reputation: 3651
Yes, exactly as you pointed out, you put the return in the callback function. the all()
function has no return statement, and by default all functions will return undefined
.
The issue you're encountering is that you're now dealing with an asynchronous function that will return data at an unknown time in the future (as opposed to synchronous functions, which return data immediately to be available to the next line of code).
In this case, you're using $http methods, and $http.get()
will return a promise.
https://docs.angularjs.org/api/ng/service/$q
Check out the examples on the $http documentation. Specifically, look at what they do with the then()
functions: https://docs.angularjs.org/api/ng/service/$http
Upvotes: 1
Reputation: 468
you are doing some asynchronous calls in your code, please visit this question to get more details and information How do I return the response from an asynchronous call?
Upvotes: 1