Reputation: 223
I have the following code and after the first query the response data is undefined? Does anyone know the reason behind this?
--- json data ---
{
"weddings": [
{
"id": "1",
"name": "D",
"currency": [
{"USD": "10"},
{"KHR": "20000"}
],
"date": "12/12/2012",
"place": "Bopha Tep",
"paid": false
},
{
"id": 2,
"name": "C",
"currency": [
{"USD": "10"},
{"THB": "200"}
],
"date": "13/12/2012",
"place": "Bopha Charkasamrong",
"paid": false
},
{
"id": 3,
"name": "A",
"currency": [
{"KHR": "10000"},
{"THB": "200"}
],
"date": "14/12/2012",
"place": "Bopha Charkasamrong",
"paid": false
},
{
"id": 4,
"name": "B",
"currency": [
{"KHR": "20000"},
{"THB": "100"},
{"USD": "20"}
],
"date": "15/12/2012",
"place": "Bopha Charkasamrong",
"paid": false
}
]
}
--- Factory ---
.factory('WeddingService',['$resource',function($resource){
var path = 'app/scripts/factories/data/weddings.json';
var data;
var resource = $resource(path,{},{
query: { method: "GET", isArray: false }
});
var weddings = function(){
resource.query().$promise.then(function(response){
data = response.weddings;
});
return data;
}
return {
list: function(){
if(data){
console.log("returning cached data");
return data;
}else{
console.log("getting countries from server");
return weddings();
}
},
get: function(find_id){
return _.findWhere(this.list(),{id:find_id});
},
}
}])
--- Controller ---
$scope.weddings = wedding.list();
console.log($scope.weddings);
---Log---
getting countries from server
undefined
Upvotes: 1
Views: 1350
Reputation: 19748
Fetching the data from the server is async so you need to use the promise from the resource to know when the data has been resolved and to get the data. See https://docs.angularjs.org/api/ngResource/service/$resource specifically search for $promise also see this other SO post:
Forgot about this post but
.factory('WeddingService',['$resource',function($resource){
var path = 'app/scripts/factories/data/weddings.json';
var data;
var resource = $resource(path,{},{
query: { method: "GET", isArray: false }
});
var weddings = function(){
//this will return the promise from the call to .then
return resource.query().$promise.then(function(response){
data = response.weddings;
});
}
return {
list: function(){
if(data){
console.log("returning cached data");
return $q.when(data); // return a promise to keep it consistent
}else{
console.log("getting countries from server");
return weddings();
}
},
get: function(find_id){
return _.findWhere(this.list(),{id:find_id});
},
}
}])
controller
wedding.list().then(function(data){
$scope.weddings = data;
console.log(data);
});
In reality I'd typically just make a reference to WeddingService from the scope or controller definition and access the data through the factory in most cases, but having the setup to return a promise for the data works well to expose the async nature of the request.
Upvotes: 1
Reputation: 17973
It seems you are using data before it is set
var weddings = function(){
resource.query().$promise.then(function(response){
data = response.weddings;
});
// data is not set until the query above is completed
return data;
}
You need to either return the promise and wait for that when using the code, or use the $broadcast('event');
and $on('event', function() { })
event system to trigger your other code when the data is downloaded completely.
You can use the first option like the following:
var weddings = function(){
data = resource.query(function(result) {
console.log('wedding is set to ', result);
},
function(error) {
console.error('something went wrong ', error);
});
return data;
}
Now in your code that uses weddings()
you can use $promise
to wait for the data and if the query is complete, you can use data like you normally would.
When using bindings from angular html you can also use data directly, since the view will be updated when the data is downloaded.
Upvotes: 0