Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

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.

share|improve this question
up vote 2 down vote accepted

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

share|improve this answer
    
I understand the difference between a service and factory, but even if I just make a simple function or attribute for WebApi and call it from a controller, the WebApi object is empty. Why is that? – user3181113 Jun 5 '14 at 8:54
    
Because it needs to be returned, let me show you a simple example to see what I mean. – Shomz Jun 5 '14 at 12:21
1  
Ahhh, I understand now. Thank you. – user3181113 Jun 5 '14 at 12:47

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});
          }
        ]);
share|improve this answer
    
The console blows up with errors and states TypeError: undefined is not a function and points to the WebApi.getProfile() function in the UserCtrl. I logged the WebApi object in the console and it still says Object {} – user3181113 Jun 5 '14 at 8:09
    
We are missing return from the factory so i have edited with return could you try now – Ajay Beniwal Jun 5 '14 at 8:26
    
My code is identical to yours, and still, I get TypeError: undefined is not a function because the object is empty. It's so weird because the controller knows of the factory and still can't communicate with it. I even put in a simple function that returns "a string" and it still does not appear in the WebApi object. Do you have any idea why this is? Is it somehow in my dependencies? – user3181113 Jun 5 '14 at 8:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.