13

I am attempting to lazy load a controller and template in my UI-Router router.js file, but am having difficulty with the template.

The controller loads properly, but after that is loaded, we must load the template and this is where things go wrong.

After ocLazyLoad loads the controller, we resolve an Angular promise which is also included in the templateProvider. The issue is instead of returning the promise (templateDeferred.promise) after the file is done loading, the promise is returned as an object.

.state('log_in', {
    url: '/log-in',
    controller: 'controllerJsFile',
    templateProvider: function($q, $http) { 
      var templateDeferred = $q.defer();

        lazyDeferred.promise.then(function(templateUrl) {
        $http.get(templateUrl)
        .success(function(data, status, headers, config) {
            templateDeferred.resolve(data);
        }).
        error(function(data, status, headers, config) {
            templateDeferred.resolve(data);
        });
  });
  return templateDeferred.promise;
 },
 resolve: {
    load: function($templateCache, $ocLazyLoad, $q) {
        lazyDeferred = $q.defer();

        var lazyLoader = $ocLazyLoad.load ({
          files: ['src/controllerJsFile']
        }).then(function() {
          return lazyDeferred.resolve('src/htmlTemplateFile');
        });
        return lazyLoader;
    }
 },
 data: {
  public: true
 }
})
T J
  • 42,762
  • 13
  • 83
  • 138
Rjdlee
  • 739
  • 1
  • 6
  • 22
  • 1
    There is a very detailed answer http://stackoverflow.com/a/27754025/1679310 how to use **RequireJs**, **UI-Router** and make that all loading stuff lazily. Maybe here could be found other interseting way http://stackoverflow.com/q/27465289/1679310 – Radim Köhler Jan 28 '15 at 07:05
  • Radim, I am trying to load the template from an HTML file rather than just having it inline. – Rjdlee Jan 28 '15 at 19:36
  • Here is another example of how to use oclazyload http://www.syntaxsuccess.com/viewarticle/55484016883215ac604c68c3 – TGH May 06 '15 at 01:46

2 Answers2

11

Ok, thanks for the responses, but I have figured it out.

.state('log_in', {
url: '/log-in',
controller: 'controllerJsFile',
templateProvider: function() { return lazyDeferred.promise; },
resolve: {
    load: function($templateCache, $ocLazyLoad, $q, $http) {
        lazyDeferred = $q.defer();

        return $ocLazyLoad.load ({
          name: 'app.logIn',
          files: ['src/controllerJsFile.js']
        }).then(function() {
          return $http.get('src/htmlTemplateFile.tpl.html')
            .success(function(data, status, headers, config) {
              return lazyDeferred.resolve(data);
            }).
            error(function(data, status, headers, config) {
              return lazyDeferred.resolve(data);
            });
        });
    }
},
data: {
  public: true
}

})

So, after some more reading, I realized I had an issue with my promises. We create one called lazyDeferred which is the one to be returned to templateProvider and is declared as a global variable. templateProvider waits for the promise to be fulfilled.

After we load our controller, we create an XHR/ $http request to retrieve the template file. $http.get is a promise so we can return that, $ocLazyLoad.load also is a promise so we can return that as well. Finally, we just need to resolve the lazyDeferred one and that I think balloons through the promises and resolves all of them.

I apologize if this was not very clear, I'm not 100% sure of how this works.

Rjdlee
  • 739
  • 1
  • 6
  • 22
4

In case you'd like to lazily load the controller, I would suggest follow these detailed answers:

In case we need to load dynamically the HTML template, it is much more easier. There is an example from this Q & A

(the working plunker)

$stateProvider
  .state('home', {
    url: '/home',
    //templateUrl: 'index5templateA.html',   (THIS WORKS)
    templateProvider: function(CONFIG, $http, $templateCache) {
        console.log('in templateUrl ' + CONFIG.codeCampType);

        var templateName = 'index5templateB.html';

        if (CONFIG.codeCampType === "svcc") {
             templateName = 'index5templateA.html';
        } 
        var tpl = $templateCache.get(templateName);

        if(tpl){
          return tpl;
        }

        return $http
           .get(templateName)
           .then(function(response){
              tpl = response.data
              $templateCache.put(templateName, tpl);
              return tpl;
          });
    },

You can check these as well:

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335