0

I am kind of new to the AngularJS framework and I am trying to migrate my test project using the standard router to use the UI-router, but I get the following error:

Error: [ng:areq] Argument 'mainCtrl' is not a function, got undefined

What I have done so far is:

Controller:

// mainCtrl.js
angular.module("sm-web")
    .controller('mainCtrl',['$scope',
            function($scope) {
                ...
    }]);

Router:

angular.module('sm-web', ['ui.router'])
    .config(['$stateProvider', '$urlRouterProvider', function( $stateProvider, $urlRouterProvider ) {

    $urlRouterProvider.otherwise('root');

        $stateProvider
            .state('root', {
                url: '',
                templateUrl: path + 'ng/sm/view/main.html',
                controller: 'mainCtrl'
        });

    }]);

Index:

<body ng-controller="mainCtrl">
    <main-menu></main-menu>
    <div class="container">
        <div ui-view></div>
    </div>
</body>

This works when I use the standard router, but not with the UI-router. Does anyone have any idea of what I am doing wrong?

7
  • Put a ' after $scope in your controller Commented Sep 7, 2015 at 15:31
  • 2
    no need to write ng-controller="mainCtrl" you already bind mainCtrl to ng/sm/view/main.html template in your router. Commented Sep 7, 2015 at 15:32
  • 1
    The otherwise method receives an url, not a state. I'm not sure that it's cousing your problems, but give it a try. Commented Sep 7, 2015 at 16:16
  • Is the mainCtrl.js file loaded before the file that contains the router config? Commented Sep 7, 2015 at 17:04
  • @SunilD. I have tried to loading them in different orders without success. :( Commented Sep 7, 2015 at 17:34

2 Answers 2

1

It seems you have an issue w/the order you declare things. For you to declare the module "sm-web" you need to do this:

angular.module('sm-web', ['ui.router']);

Note that the presence of that 2nd array argument is what tells Angular that you're declaring the module (eg. creating a new module). When you leave that 2nd argument out, you're retrieving the module you previously declared.

So with that in mind, look at how it all is coming together in your code:

  • To declare the controller, you retrieve the module "sm-web" (by leaving off the 2nd array arg).
  • When configuring the router states, you declare a new module "sm-web". But note that immediately after you declare this new module, you try to register a state with the controller named "mainCtrl" -- but that doesn't exist yet.

You need to create the module somewhere before doing all of the above. After creating the module, then register the controller on the module. Finally, with the controller defined, then you can register the state that uses the controller.

There's too many ways to solve this ordering problem, so I'm not going to suggest anything further. It depends on what files the code lives in and the order you load those files in index.html.

Sign up to request clarification or add additional context in comments.

2 Comments

Well, as I told SunilD I have tried to order the imports differently, but without success. However, even if there is an error with the imports, how come the code works using a different router?
Turns out this was correct. I was incorrectly adding ui.router in my router.js instead of in my app.js (I didn't show the contents of this file in my question because I thought nothing was wrong with it). Thanks a lot!
0

In order to avoid your problem change your code by the following code:

// mainCtrl.js

angular.module("sm-web")
    .controller('mainCtrl',['$scope',
            function($scope) {
                ...
    }]);

1 Comment

Sorry, the ' is missing because I accidentally removed it when I edited the question. My bad.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.