Search code examples
javascriptangularjsrequirejsopenlayersrequire

Using OpenLayers with RequireJS and AngularJS


I'm trying to get an app running that uses both AngularJS and RequireJS. I'm having problems getting my OpenLayers lib to work in this setup.

I set the main AMD-modules in the main.js:

require.config(
    {
        baseUrl: 'scripts',
        paths: {
            // Vendor modules
            angular: 'vendor/angular/angular',
            openLayers: 'vendor/openlayers-debug',
            other modules.....
        },
        shim: {
            angular: {
                exports: 'angular'
            },
            openLayers: {
                exports: 'OpenLayers'
            },
            other modules....
        }
    }
);

require(['openLayers',
        'angular',
        'app',
        'controllers/olMapController',
        'directives/olMap',
        other modules...
    ], function(OpenLayers) {
        return OpenLayers;
    }
);

Then in the angular controller I use for the initialisation of OpenLayers, I try to indicate that openlayers-debug.js is a dependency:

define(['openLayers'],
    function(OpenLayers) {
        controllers.controller('olMapController', ['$scope', function(scope) {
            console.log('Loaded olMapController. OpenLayers version: ' + OpenLayers.VERSION_NUMBER);
        }]);
    }
);

Well, this doesn't work. SOMETIMES the olMapController function is executed, but mostly not. The console then just displays an error stating:

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

So, I think OpenLayers hasn't finished loading yet, but somehow require thinks it has and continues loading code that depends on OpenLayers, in this case the olMapController. It then can't find its dependency, whereupon Angular returns this error message. Or something like that...? Sometimes something happens that makes OpenLayers load fast enought for it to be present when it is loaded as a dependency. What that is, I can't tell.

I left out other libraries and modules require and define to keep the code readable. I hope the example is still understandable.

Any ideas on what I could do to get openlayers to load well? The error message disappears when I leave the ['openLayers'] dependency out of olMapController.

Thanks in advance for any help.

Best regards, Martijn Senden


Solution

  • Sorry this answer will only contain text as your code is too big for a small example.

    I would suggest to write a directive that utilizes head.js to load libraries you need at a specific context. One could also think of a directive that initializes openLayers this way.

    I guess your error is a timing problem, because the require.js and angular.js module loading gets out of sync - more precisely there seems to be no sync at all between them.

    update
    To repeat my comment which lastly helped to lead the OP in the right direction:

    You have to decide which framework gives the tone. If you go with requireJS, then require everything and bootstrap angular manually. (Remove ng-app="" from index.html) and do `angular.bootstrap()´ when requirejs has completed. So the problem most likely is, that angular starts too early.