2

In order to set the base of my url in a factory call I need to call another factory's method to get the config. The below keeps throwing a Provider 'reportService' must return a value from $get factory method. error:

.factory('reportService', ['$resource', 'serverService',
  function($resource, serverService) {

    serverService.getConfiguration().$promise.then(function(config) {
      var base = config.reporting.url;
      return $resource(base, {}, {
        getReportResults: {method: 'POST', url: base + '/api/reports/:id/versions/:version'}
      });
    });
  }])

serverService:

angular.module('app')
  .factory('serverService', ['$resource',
    function($resource) {
      var base = '/api/server/';
      return $resource(base, {}, {
        getConfiguration: {method: 'GET', url: base + 'configuration'}
      });
    }]);
1
  • Can we see the code for serverService? Commented Jul 14, 2016 at 13:00

2 Answers 2

1

If it is a factory method, it should return an instance of object. And it will be invoke only when you require/inject it to another component.

In this case your return is inside the inner function so the function won't return any project.

It should be like this:

.factory('reportService', ['$resource', 'serverService',
  function($resource, serverService) {
    var base = config.reporting.url;
    function ReportService() {
      serverService.getConfiguration().$promise.then(function(config) {
        this.resource = $resource(base, {}, {
          getReportResults: {method: 'POST', url: base + '/api/reports/:id/versions/:version'}
        });
      }.bind(this));
    }
    return new ReportService()
  }])

More explaination:

  1. a factory should return an object.

Ex:

.factory('message', function () {
  return "Hello World!"
}

so when it's injected to anther component, it will have a value of the returned object.

.controller('something', ['$scope', 'message', function ($scope, message) {}]);

then message will have value of 'Hello World!"

  1. Return in inner function won't count.

Ex:

.factory('message', function () {
  http.get(...).then(function (data) {
    return "Hello World!"
  });
}
Sign up to request clarification or add additional context in comments.

2 Comments

When running the above I get reportService.getReportResults is not a function. Note: I moved var base = config.reporting.url; inside serverService.getConfiguration.
You need to call like reportService.resource.getReportResults can you explain what getConfiguration do? I think if it's a config you can put it into a javascript file and import it instead of calling async like that.
1

Your factory must return some function. Here in your reportService, you have defined the function but didn't return it.

Change it to the following,

.factory('reportService', ['$resource', 'serverService',
    function($resource, serverService) {
        return {
            function_one(): function() {
                return serverService.getConfiguration().$promise.then(function(config) {
                    var base = config.reporting.url;
                    return $resource(base, {}, {
                        getReportResults: {method: 'POST', url: base + '/api/reports/:id/versions/:version'}
                    });
                });      
            }, //add how many ever functions you want by separating with comma
            function_two: function() {
                // your second function
            }
        };
}]);

Now you can access your required function as follows in any controller,

reportService.function_one()
  .then(function (response) {
      // your logic
  });

2 Comments

When I add return in front of that function I get an Expression or comma expected warning in my IDE and an Unknown provider: reportServiceProvider <- reportService <- reportQueueController in the console.
@MattDionis I've made a syntax mistake. Can you check my edited answer?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.