AngularJS : Service object empty
-
22-12-2019 - |
質問
I'm new to Angular and I've been struggling for a while trying to call a factory that uses Restangular in one of my controllers. Here is the controller:
'use strict';
angular.module('myApp')
.controller('UserCtrl', ['WebApi', function($scope, WebApi) {
$scope.user = WebApi.getProfile(1);
}
]);
Whenever I call the WebApi factory in my controller, the WebApi object is empty. When I call the method, it will then return undefined. When I log the object in the console, I get
Object {}
Here is my factory:
"use strict";
angular.module("myApp.services", ["restangular"])
.factory("WebApi", ["Restangular", function(Restangular) {
var getProfile;
Restangular.withConfig(function(RestangularConfigurer) {
RestangularConfigurer.setBaseUrl("http://127.0.0.1:3000/api/v1");
});
getProfile = function(id) {
Restangular.one("users", id).get().then(function(data) {
return data;
});
};
}
]);
App module:
'use strict';
angular.module('myApp', ['ngCookies', 'ngSanitize', 'ui.router', 'myApp.services']);
And it's included in my index html:
<script src="scripts/app.js"></script>
<script src="scripts/controllers/main.js"></script>
<script src="scripts/services/webapi.js"></script>
<script src="scripts/controllers/user.js"></script>
What am I doing wrong? Thank you in advance.
解決
This one is an async call:
Restangular.one("users", id).get().then(function(data) {
return data;
});
and it doesn't return anything to its parent function.
You can return a promise from the parent function, and resolve it inside the then
callback I mentioned above (instead of return data;
).
The other thing is that factory needs to return an object in order for its properties to be available. There are some really good answers here: angular.service vs angular.factory
UPDATE
Based on the question in the comments, here is what I mean by having to return an object:
angular.module("myApp.services", ["restangular"])
.factory("WebApi", ["Restangular", function(Restangular) {
var getProfile;
getProfile = function(id) {
// this function is not visible from outside
};
// but if you do this:
return {
someValue: 3, // accessible via WebApi.someValue
someFunction: function(){alert('me too')},
getProfile: getProfile // now it works as WebApi.getProfile(),
etc: etc
}
// all of these above are now accessible
}
]);
See the simple example here: http://plnkr.co/edit/KGUqCVJqeEcD5d6m7sVw?p=preview
他のヒント
You should modify your code to use promise and return the promise from there see dummy code
angular.module("myApp.services", ["restangular"])
.factory("WebApi", ["Restangular","$q", function(Restangular,$q) {
Restangular.withConfig(function(RestangularConfigurer) {
RestangularConfigurer.setBaseUrl("http://127.0.0.1:3000/api/v1");
});
return {
getProfile : function(id) {
var deferred = $q.defer();
Restangular.one("users", id).get().then(function(data) {
deferred.resolve(data);
});
return deferred.promise;
};
}
}
]);
'use strict';
angular.module('myApp')
.controller('UserCtrl', ['WebApi', function($scope, WebApi) {
WebApi.getProfile(1).then(function(data){$scope.user=data});
}
]);