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.
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');
}
)
}
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;
});
}
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.