Join the Stack Overflow Community
Stack Overflow is a community of 6.5 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

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
 }
})
share|improve this question
1  
There is a very detailed answer 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 stackoverflow.com/q/27465289/1679310 – Radim Köhler Jan 28 '15 at 7: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 syntaxsuccess.com/viewarticle/55484016883215ac604c68c3 – TGH May 6 '15 at 1:46
up vote 7 down vote accepted

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.

share|improve this answer

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:

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.