I have the following scenario, I need data from a particular url. I have written a function which takes parameter 'url'. Inside the function I have the $http.get method which makes a call to the url. The data is to be returned to the calling function
var getData = function (url) {
var data = "";
$http.get(url)
.success( function(response, status, headers, config) {
data = response;
})
.error(function(errResp) {
console.log("error fetching url");
});
return data;
}
The problem is as follows, $http.get is asynchronous, before the response is fetched, the function returns. Therefore the calling function gets the data as empty string. How do I force the function not to return until the data has been fetched from the url?
Take a look at promises to overcome such issues, because they are used all over the place, in angular world.
You need to use $q
var getData = function (url) {
var data = "";
var deferred = $q.defer();
$http.get(url)
.success( function(response, status, headers, config) {
deferred.resolve(response);
})
.error(function(errResp) {
deferred.reject({ message: "Really bad" });
});
return deferred.promise;
}
Here's a nice article on promises and $q
UPDATE:
FYI, $http
service itself returns a promise, so $q
is not necessarily required in this scenario(and hence an anti-pattern).
But do not let this be the reason to skip reading about $q and promises.
So the above code is equivalent to following:
var getData = function (url) {
var data = "";
return $http.get(url);
}
You can use $q.all() method also to solve this problem
var requestPromise = [];
var getData = function (url) {
var data = "";
var httpPromise = $http.get(url)
.success( function(response, status, headers, config) {
data = response;
})
.error(function(errResp) {
console.log("error fetching url");
});
requestPromise.push(httpPromise);
}
in the calling function
$q.all(requestPromise).then(function(data) {
//this is entered only after http.get is successful
});
make sure to inject $q as a dependency. Hope it helps
A typical way to do what you want is like so:
var getData = function(url, callback) {
$http.get(url).success(function(response) {
callback && callback(response);
});
};
Used like:
getData('/endpoint', function(data) {
console.log(data);
});
You function seems redundant. Just use $http.get(url)
, since you aren't really doing anything else before you use it anyway.
var url = 'foo/bar';
$http
.get(url)
.success( function(response, status, headers, config) {
$scope.data = response;
})
.error(function(errResp) {
console.log("error fetching url");
});
Or if you need to access the promise later just assign it to variable;
var promise = $http.get(url);
// some other code..
promise.then(function(data){
//.. do something with data
});