1

I am using some JavaScript libraries that may or may not be used depending on whether a user navigates to a particular view. How can I hold off loading and still satisfy all Angular dependencies.

For example, I am using the Google maps API with ng-map (a directive for Google maps off git hub). If I load everything in HTML HEAD then it all works fine. I attempted to move the script tags into the view partial that uses ng-map but I get an error because angular.module must be passed the ng-map module. If I move only the Google API script to the view partial I get a different error that Google is not defined for ng-map.

Bottom line is, do you have to load all script/modules on the initial load?

1
  • I have an example project for lazy loading Angular components and independent scripts here, using RequireJS for script management. In general, lazy loading in Angular is a pain. This project may (or may not) provide you with some ideas, solutions etc. Commented May 13, 2015 at 15:21

2 Answers 2

1

If you are using third party libraries, you can load them when needed using a lazy load option like this:

Create a service:

.service('lazyLoad', ['$document', '$q', '$timeout', function ($document, $q, $timeout) {

    function loader(createElement) {
        var promises = {};

        return function (url) {
            if (typeof promises[url] === 'undefined') {
                var deferred = $q.defer();
                var element = createElement(url);

                element.onload = element.onreadystatechange = function (e) {
                    $timeout(function () {
                        deferred.resolve(e);
                    });
                };
                element.onerror = function (e) {
                    $timeout(function () {
                        deferred.reject(e);
                    });
                };

                promises[url] = deferred.promise;
            }

            return promises[url];
        };
    }


    this.loadScript = loader(function (src) {
        var script = $document[0].createElement('script');

        script.src = src;

        $document[0].body.appendChild(script);
        return script;
    });


    this.loadCSS = loader(function (href) {
        var style = $document[0].createElement('link');

        style.rel = 'stylesheet';
        style.type = 'text/css';
        style.href = href;

        $document[0].head.appendChild(style);
        return style;
    });
}])

Then on your Angular Module add a service for your third party library:

.service('ckeditorService', function ($window, $q, lazyLoad) {
    this.CKEDITOR = function () {
        var deferred = $q.defer();

        if (typeof $window.CKEDITOR === "undefined") {
            lazyLoad.loadScript('lib/ckeditor/ckeditor.js').then(function () {
                deferred.resolve($window.CKEDITOR);
            }).catch(function () {
                console.log('Error loading : lib/ckeditor/ckeditor.js');
                deferred.resolve($window.CKEDITOR);
            });
        } else {
            deferred.resolve($window.CKEDITOR);
        }

        return deferred.promise;
    }

})

Then in your Controller where you want to use the service:

.controller('maintainItemDetailsController', function (ckeditorService) {

     ckeditorService.CKEDITOR().then(function (CKEDITOR) {
        self.editable = true;
        CKEDITOR.inline('description');
        CKEDITOR.inline('additional_info');
    });

})

In this example I am using the ckeditor library but in your case it will be the Google maps library

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

1 Comment

I am using above services and controller to load ckeditor.js and anular ckeditor directive. Both libraries loaded and added correctly. I am also manually injecting the required module 'ckeditor' but CKEDITOR is not being populated.
0

You should split your scripts into entry-specific modules, for that task you can use browserify with fuctor-bundle or partion-bundle for more flexibility.

That's about gathering your scripts, and about gathering angular modules (which are not the same) you can look at this answer.

Comments

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.