1

EDIT: using YEOMAN to scaffold my app,

I have the following YEOMAN generated provider

'use strict';

angular.module('myApp')
  .provider('myProvider', function () {

    // Private variables
    var salutation = 'Hello';

    // Private constructor
    function Greeter() {
      this.greet = function () {
        return salutation;
      };
    }

    // Public API for configuration
    this.setSalutation = function (s) {
      salutation = s;
    };

    // Method for instantiating
    this.$get = function () {
      return new Greeter();
    };
  });

and I'm trying inject it in my app config like so:

'use strict';

angular.module('myApp', [
        'ngRoute',
        'myProvider'
    ])
    .config(function ($routeProvider, myProvider) {
        $routeProvider
            .when('/', {
                templateUrl: 'views/main.html',
                controller: 'MainCtrl'
            })
            .otherwise({
                redirectTo: '/'
            });
    });

And I get the following error:

Uncaught Error: [$injector:modulerr] Failed to instantiate module lpSocialApp due to:
Error: [$injector:modulerr] Failed to instantiate module myProvider due to:
Error: [$injector:nomod] Module 'myProvider' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

What am I missing?

Shlomi Schwartz
  • 8,693
  • 29
  • 109
  • 186
  • 1
    check out this link [Angular.js: service vs provider vs factory](http://stackoverflow.com/questions/15666048/angular-js-service-vs-provider-vs-factory) – Ravi Jan 02 '14 at 11:02

3 Answers3

4

I can see two mistakes in your code:

1) You cannot inject 'myProvider' in your application module since 'myProvider' is defined in your application module.

2) The name of 'myProvider' is wrong, Angular automatically append 'Provider' to your provider.

Here is the fix:

1) Define your provider in a dedicated module and add this new module in your application module dependencies.

2) Rename your provider to 'my' (or inject 'myProviderProvider' in your config function) :

angular.module('myProviderModule', [])
    .provider('my', function () { // or 'myProvider'

        // Private variables
        var salutation = 'Hello';

        // Private constructor
        function Greeter() {
            this.greet = function () {
                return salutation;
            };
        }

        // Public API for configuration
        this.setSalutation = function (s) {
          salutation = s;
        };

        // Method for instantiating
        this.$get = function () {
            return new Greeter();
        };
    });

angular.module('myApp', [
    'ngRoute',
    'myProviderModule'
])
.config(function ($routeProvider, myProvider) { // or 'myProviderProvider'
    $routeProvider
        .when('/', {
            templateUrl: 'views/main.html',
            controller: 'MainCtrl'
        })
        .otherwise({
            redirectTo: '/'
        });
});

See this fiddle: http://jsfiddle.net/Z3k2s

Mickael
  • 5,711
  • 2
  • 26
  • 22
  • Thanks for your reply, I can see how this can fix my issues, however I'm using YEOMAN to generate the code, and want to believe they are using best practices there ... could it be a bug in their generator? – Shlomi Schwartz Jan 02 '14 at 12:14
  • @DavinTryon The name 'myProvider' is not wrong, but AngularJS automatically append 'Provider' to parameters in config function during injection.The solution is to remove 'Provider' suffix (myProvider -> my) or to add 'Provider' suffix in config function ('myProvider' -> 'myProviderProvider'). – Mickael Jan 02 '14 at 13:15
1

You are confusing provider with modules. Modules include set of providers, services and factories.

You also should NOT add provider suffix when defining a provider, or else you have to inject it like myProviderProvider.

Also you look like you are confusing the syntax on angular.module:

// create a new module foo.bar with dependency to ngRoute
angular.module('foo.bar', ['ngRoute']);

// create a new module woo.hoo with NO dependency
angular.module('woo.hoo', []); 

// get already created module foo.bar
angular.module('foo.bar')

Your code fixed:

'use strict';

angular.module('someModule', [])
  .provider('my', function () {

    // Method for instantiating
    this.$get = function () {
      return {}// return something
    };
  });



'use strict';

angular.module('myApp', [
        'ngRoute',
        'someModule'
    ])
    .config(function ($routeProvider, myProvider) {
        $routeProvider
            .when('/', {
                templateUrl: 'views/main.html',
                controller: 'MainCtrl'
            })
            .otherwise({
                redirectTo: '/'
            });
    });
Umur Kontacı
  • 35,403
  • 8
  • 73
  • 96
  • `or else you have to inject it like myProviderProvider`. I'm not sure this is true. Angular will add "Provider" to the end (in the injector), but both `myProvider` and `myProviderProvider` should work when using the provider. – Davin Tryon Jan 02 '14 at 11:44
  • Thanks for your reply, I can see how this can fix my issues, however I'm using YEOMAN to generate the code, and want to believe they are using best practices there ... could it be a bug in their generator? – Shlomi Schwartz Jan 02 '14 at 12:13
  • @DavinTryon No. In the config phase, you have to inject it as `myProviderProvider` but in the run phase, you can inject it as `myProvider` but it wouldn't be a provider anymore, it would be a service which has a name of provider, and that would be misleading. – Umur Kontacı Jan 02 '14 at 13:04
  • @ShlomiSchwartz I don't know the recent news about yeoman but it gives you the generated code for you to start coding. You are expected to change it. – Umur Kontacı Jan 02 '14 at 13:05
  • @UmurKontacı While that's correct, the yeoman output is supposed to work as-is so that you have a known-good base to start from. So, yes, I'd agree that it's a bug. – Matthias Urlichs Oct 27 '14 at 15:12
0

You are attempting to load a dependent module named myProvider:

angular.module('myApp', [
        'ngRoute',
        'myProvider'
    ])

myProvider is already in the myApp module, so you can do this:

angular.module('myApp', [
        'ngRoute'
    ])
    .config(function ($routeProvider, myProvider) {
Davin Tryon
  • 66,517
  • 15
  • 143
  • 132