Using angularJS with requireJS - cannot read property 'module' of undefined

15,014

Looking at the sources for Angular, I do not see anywhere that it calls RequireJS' define so you need a shim for it. Add this to your shim configuration:

angular: {
    exports: "angular"
}

By the way, the priority field in your configuration is obsolete. Either you use RequireJS 2.x which ignores this field because priority is supported only by RequireJS 1.x. Or you use RequireJS 1.x which would honor priority but would ignore the shim field because shim was introduced in 2.x. My suggestion: use RequireJS 2.x and remove priority.

Share:
15,014
Kaushik Lakshmikanth
Author by

Kaushik Lakshmikanth

Updated on June 27, 2022

Comments

  • Kaushik Lakshmikanth
    Kaushik Lakshmikanth almost 2 years

    I had started writing an app using angularJS. After a few weeks, I suddenly realized that I should have used require JS from the beginning to load my modules. Yes, I know, it was stupid. But it is what it is. So I've tried to convert my code to suit requireJS now.

    This is my main.js

    requirejs.config({
    baseUrl: "js",
    paths: {
        jquery:'jquery-1.7.min',
        angular: 'angular',
        angularRoute:'angular-route',
        mainApp:'AngularApp/app'
    
    },
     priority:['angular'],
    shim:{
    
        angularRoute:{
            deps:["angular"]
        },
        mainApp:{
            deps:['angularRoute']
        }
    }});
    
    require(['angular','angularRoute', 'mainApp'],
        function(angular, angularRoute, app)
        {
            angular.bootstrap(document, ['ServiceContractModule']);
        });
    

    This is my app.js

    define(['angular',
        'angularRoute',
        'AngularApp/services',
        'AngularApp/directives',
        'AngularApp/controllers'],
        function(angular, angularRoute, services, directives, controllers)
        {
            console.log("sup");
            var serviceContractModule = angular.module('ServiceContractModule',[ 'ngRoute', services, directives, controllers ]);
            serviceContractModule.config(function($routeProvider,$locationProvider) {
                $routeProvider.when('/contractNumber/:contractNumbers', {
                    controller : 'ContractController',
                    templateUrl : './contractSearchResult',
                    reloadOnSearch : true
                }).when('/serialNumber/:serialNumbers', {
                    controller : 'SerialController',
                    templateUrl : './serialSearchResult'
                }).when('/QuoteManager',{
                    controller : 'QuoteManagerController',
                    templateUrl: './quoteManagerView'
                }).when('/QuoteManagerHome',{
                    controller : 'QuoteManagerController',
                    templateUrl: './quoteManagerHome'
                });
            });
    
            return serviceContractModule;
        });
    

    This is my directives.js file

    define(['angular',
        'AngularApp/Directives/tableOperations',
        'AngularApp/Directives/line',
        'AngularApp/Directives/listOfValues'],
        function(
        angular,
        tableOperations,
        line,
        listOfValues)
        {
            var directiveModule = angular.module('ServiceContractModule.directives');
            directiveModule.directive('tableoperations', tableOperations);
            directiveModule.directive('line', line);
            directiveModule.directive('listOfValues', listOfValues);
            return directiveModule;
        }
    

    )

    And this is my services.js file

    define(['angular',
        'AngularApp/Services/quoteManagerSearch'],
        function(angular, quoteManagerSearch)
        {
            var serviceModule = angular.module('ServiceContractModule.services');
            serviceModule.factory('searchRequestHandler', quoteManagerSearch);
            return serviceModule;
        }
    

    )

    When I run my page, the current error I am getting is

    Uncaught TypeError: Cannot read property 'module' of undefined directives.js:14

    Uncaught TypeError: Cannot read property 'module' of undefined services.js:5

    This seems to be happening on this particular line

    var directiveModule = angular.module('ServiceContractModule.directives');
    

    I think for some reason, the angular file is not getting loaded. Although when I run the page, I can see all the js files being loaded in the correct order in chrome.

    Any ideas guys? Need quick help! Thanks!

  • Kaushik Lakshmikanth
    Kaushik Lakshmikanth about 10 years
    Hey, thanks so much. That makes a lot of sense. I removed the priority and added the exports property for angular. Now I seem to be getting a timeout error for angularRoute and mainApp. AngularRoute doesn't seem to load after the angular file. Is there a problem with my dependencies?
  • Louis
    Louis about 10 years
    There's nothing that jumps at me from what I can see in your question. When you check the network requests your browser makes, is it downloading the right stuff for angularRoute and mainApp?
  • Kaushik Lakshmikanth
    Kaushik Lakshmikanth about 10 years
    Nope. It loads main.js, then angular.js and stops. I've also added the exports property for the angularRoute. Either way, I tried it with and without. Same error both times.
  • Louis
    Louis about 10 years
    If the module you load as mainApp is the same module that you refer to with "This is my app.js", then you do not need a shim configuration for it because you use define to define it. This could explain some of the issues you are experiencing.
  • Kaushik Lakshmikanth
    Kaushik Lakshmikanth about 10 years
    Yeah I did that. But something weird happened. App.js seems to load before angular. That's really weird, as I've mentioned that in my define tag in app.js. And the same earlier problem persists for angularRoute. Just doesn't load. All the other modules seem to load though. This is some pretty weird behaviour. Maybe some other files are getting imported somewhere else and causing some issues.
  • Louis
    Louis about 10 years
    It is okay if app.js loads before angular. RequireJS loads it, executes the define, sees that it needs angular (and other stuff) and loads angular and the other dependencies and then executes the factory function (the callback passed to define). What is not okay is if the factory function passed to define executes before angular is loaded. As for angularRoute, is there a define call in it? If yes, then no shim needed.
  • Kaushik Lakshmikanth
    Kaushik Lakshmikanth about 10 years
    Oh okay. angular-route.js is a library file, just like angular.js. But it should be loaded after angular.