Reputation: 423
I have a factory that returns a JSON object using angular. $http.get request is getting data because I can see it in console.log(data). I also know if I hard code the JSON object into the factory the controller receives the data and displays in the view correctly
My questions is this why is list: function(callback)
not returning the
data to my controller even though $http.get is getting it?
.factory('countries', function($http){
return {
list: function(callback){
$http.get('../test.json').success(function(data, status, headers) {
console.log("success");
console.log(data);
//console.log(status);
}).error(function(data, status) {
//console.log("error");
// console.log(data);
// console.log(status);
});
}
};
/*
var x = {
list: [
{
"name": "China",
"population": 1359821000,
"flagURL": "//upload.wikimedia.org/wikipedia/commons/f/fa/Flag_of_the_People%27s_Republic_of_China.svg",
"capital": "Beijing",
"gdp": 12261
},
{
"name": "India",
"population": 1205625000,
"flagURL": "//upload.wikimedia.org/wikipedia/en/4/41/Flag_of_India.svg",
"capital": "New Delhi",
"gdp": 4716
},
{
"name": "United States of America",
"population": 312247000,
"flagURL": "//upload.wikimedia.org/wikipedia/en/a/a4/Flag_of_the_United_States.svg",
"capital": "Washington, D.C.",
"gdp": 16244
}
]
};
console.log(x);
return x;
*/
})
.controller('View2Ctrl', function ($scope, countries){
$scope.countries = countries.list;
});
Upvotes: 1
Views: 4066
Reputation: 52837
You probably want something like this:
.factory('countries', function($http){
var list = [];
$http.get('../test.json').success(function(data, status, headers) {
angular.copy(data, list);
})
return {
list: list
}
};
Then you can bind to the list like this:
.controller('View2Ctrl', function ($scope, countries){
$scope.countries = countries.list;
});
An alternative, equally valid approach is this:
.factory('countries', function($http){
return {
list: function() { return $http.get('../test.json'); }
}
};
Then in your controller:
.controller('View2Ctrl', function ($scope, countries){
$scope.countries = [];
countries.list().success(function(data) {
$scope.countries = data;
});
});
Remember that $http.get('../test.json')
is already a promise, which is why you can return it without any unnecessary promise/resolve handling.
Upvotes: 2
Reputation: 2541
First of all it is better to use then
and catch
instead of success
and error
. That way you are getting the advantage of the $http
promise.
Second of all you need to return the data in your list function like so:
$http.get('../test.json')
.then(function(response) {
return response;
})
.catch(function(response) {
console.log(response);
});
Then in your controller you just need to call the function:
$scope.countries = countries.list();
That's it.
BONUS: How I do it.
In my factory I have fetch set and get functions and an array variable for the data.
.factory('countries', function($http) {
var service = {
fetch: fetch,
get: get
};
var countries = [];
return service;
function fetch() {
$http.get('../test.json')
.then(set)
.catch(function(err) {
console.log(err);
});
}
function set(data) {
countries = data;
}
function get() {
return countries;
}
});
When loading your controller you can call the fetch function to get all the countries and if you pass the get function to the controller you can call it whenever you like to get those countries you fetched already. That way you won't make additional requests for countries when you don't need them. You also get the advantage of the factory that makes a singleton. This way this data(countries) are shared across every controller where you inject countries until you remove or change the data from the factory (or refresh the page).
.controller('View2Ctrl', function ($scope, countries){
countries.fetch();
$scope.getCountries = countries.get;
});
Now in your view you can just call the get function to get the countries.
<div ng-repeat="country in getCountries()"></div>
Upvotes: 1
Reputation: 6031
Because you are not returning anything from your $http
request.
Change your code to:
.factory('countries', function($http, $q){
return {
list: function(callback){
var d = $q.defer();
$http.get('../test.json').success(function(data, status, headers) {
console.log("success");
console.log(data);
//console.log(status);
d.resolve(data);
}).error(function(data, status) {
//console.log("error");
// console.log(data);
// console.log(status);
d.reject(data);
});
return d.promise;
}
};
Upvotes: 2
Reputation: 617
I think you should call change to $scope.countries = countries.list(); to run send request to server.
Upvotes: 0