Reputation: 143
I'm using a promise to get data from a json in my service and then passing it to my controller.I'm having some problems with this.
That's my Service
getMetaData: function () {
var defer = this.$q.defer();
this.$http.get('http://localhost:8084/login-api/public/metadata/describe/Coisa')
.success(function (data, status, headers, config) {
defer.resolve(data)
})
.error(function (data, status, headers, config) {
defer.reject(status);
})
return defer.promise;
}
And here i'm calling the Service im my controller
getData: function () {
this.$scope.meta = this.EntityService.getMetaData();
var dataS = {};
this.$scope.meta.then(
function (data) {
this.$scope.metaD = data;
},
function (err) {
alert('Error');
}
)
}
And this is the error that I'm having:
TypeError: Cannot set property 'metaD' of undefined
at basic-list-controller.js:29
at l.promise.then.l (angular.js:7)
at angular.js:7
at u.$get.u.$eval (angular.js:7)
at u.$get.u.$digest (angular.js:7)
at u.$get.u.$apply (angular.js:7)
at p (angular.js:7)
at T (angular.js:7)
at XMLHttpRequest.b.onreadystatechange (angular.js:7)
And i can't see why i'm having this error. When i log the data on the console, it's there, but i can't give the value to a variable.
Upvotes: 0
Views: 64
Reputation: 3953
You can simplify it to this because using a $http service can return a promise directly and use the 'then' function to pre-process data before returning it:
getMetaData: function () {
return $http.get('http://localhost:8084/login-api/public/metadata/describe/Coisa')
.then(function (success) {
return success.data;
},
function (error) {
return error;
});
}
This should now work with the rest of your code. Note I return the entire result, if you just want the response then return 'succes.data'. Or you can check for it on controller code.
Upvotes: 0
Reputation: 49590
There are a number of things wrong with how you approach this.
First: you don't need to use $q.defer
for something that already returns a promise, like $http
- this is considered a deferred anti-pattern.
Second: avoid passing $scope
to your service - it makes it more difficult to test and upsets separation of concerns. $scope
belongs to the controller.
And so, your service can be made much simpler. You don't even need two methods - since both return the same thing
.factory("myDataService", function($http){
return {
getMetaData: function(){
return $http.get('url/to/data');
}
};
}
.controller("MainCtrl", function($scope, myDataService){
myDataService.getMetaData()
.then(function(data)){
$scope.metaD = data;
});
}
Upvotes: 1
Reputation: 164
In your success function "this" is not what you expect
function (data) {
this.$scope.metaD = data;
}
You can try setting this outside your callback like this:
var _this = this;
and inside your callback use:
function (data) {
this.$scope.metaD = data;
}
Your final code should look like:
getData: function () {
var _this = this;
this.$scope.meta = this.EntityService.getMetaData();
var dataS = {};
this.$scope.meta.then(
function (data) {
_this.$scope.metaD = data;
},
function (err) {
alert('Error');
}
)
}
Upvotes: 1