Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Controller not being initialized #33

Closed
amcdnl opened this issue Jun 17, 2014 · 28 comments
Closed

Controller not being initialized #33

amcdnl opened this issue Jun 17, 2014 · 28 comments

Comments

@amcdnl
Copy link

amcdnl commented Jun 17, 2014

I'm trying to lazy load a module. The module is injected and no errors are thrown but the controller never initializes.

My structure looks like:

/app
    /admin
        /apps
            apps.js
        admin.js
    app.js

admin.js contains the routes for all my modules that fall under the admin folder ( there is much more just shortened here ).

On init, app.js loads like:

define(['angular',
            'ui-router',
        'ocLazyLoad',
        'app/admin/admin'], function(angular){

    var app = angular.module('testapp', ['ui.router', 'oc.lazyLoad', 'admin']);

    app.config(function ($urlRouterProvider, $locationProvider, $ocLazyLoadProvider) {
        $locationProvider.html5Mode(true);

        $ocLazyLoadProvider.config({
            loadedModules: ['testapp'],
            asyncLoader: requirejs
        });
    });

    return app;
});

in my admin.js file I define all the routes for my admin section of my app like:

define(['angular'], function (angular) {

    var module = angular.module('admin', ['']);

    module.config(function ($stateProvider, $urlRouterProvider) {

        // admin/apps/apps.js
        $stateProvider.state('apps', {
            url: '/apps',
            templateUrl: 'app/admin/apps/apps.tpl.html',
            controller: 'AppsCtrl',
            resolve: {
                apps: function (AppsModel) {
                    return AppsModel.findAll();
                },
                load: function($ocLazyLoad) {
                    return $ocLazyLoad.load({
                        name: 'admin.apps', 
                        files: ['app/admin/apps/apps']
                    });
                }
            }
        });

    return module;

});

and then in apps.js I define the apps module and controller:

define(['angular'], function (angular) {

    var module = angular.module('admin.apps', []);

    module.controller('AppsCtrl', function ($rootScope, $scope) { ... });

    return module;

});

so everything loads fine and breakpoints are even hit in the apps.js file but the controller is never init'd. The ui-view is empty like:

<div class="ng-scope" ui-view=""></div>

am i missing something or is this a bug?

@amcdnl
Copy link
Author

amcdnl commented Jun 17, 2014

Also worth mentioning, I found a good post that combines RequireJS + ocLazyLoader + ui-router - http://plnkr.co/edit/OGvi01?p=preview with a SO article: http://stackoverflow.com/questions/23890623/how-can-i-add-require-js-to-my-angularjs-application

@ocombe
Copy link
Owner

ocombe commented Jun 17, 2014

Did you use the version that I just release a few hours ago or an older one ?
If you used the new version, can you test with the previous one ?

@ocombe
Copy link
Owner

ocombe commented Jun 17, 2014

@gilbox do you mind if I link your plunkr in the doc as an example of a requirejs integration ?
Also you could use the latest version 0.3.0 in your plunkr, I tried and it works fine.

@amcdnl
Copy link
Author

amcdnl commented Jun 17, 2014

@amcdnl
Copy link
Author

amcdnl commented Jun 17, 2014

Also whats the ideal convention when you have a ui-router route that has 2 separate views with their own controllers such as: http://www.screencast.com/t/yQe1Qwxw1rHb

@gilbox
Copy link

gilbox commented Jun 17, 2014

@ocombe of course you can use it. I've updated the plunk to 0.3.0.

@amcdnl Have you tried it? I don't really think it's a special case. You just have to replace templateUrl with templateProvider and add the resolve function. Of course, you don't want to actually create such a complicated resolve and templateProvider function for every view. Here is an example plunk which simplifies that part...

and here's a quick look at the simplified pattern:

    var lazyCtrlBundle = lazyBundle('app.lazy', 'lazy', 'lazy.html');

    $stateProvider
      .state('home', {
        url: "/",
        template: "<p>Hello {{name}}. Would you like to... <a href='#lazy'>load lazy</a>?</p>",
        controller: 'mainCtrl'
      })
      .state('lazy', {
        url: "/lazy",
        templateProvider: lazyCtrlBundle.templateProvider,
        controller: 'lazyCtrl',
        resolve: {
          load: lazyCtrlBundle.resolve
        }
      });

... so for each lazily-loaded view you can create another bundle with lazyBundle (bundle might not be the best name here, I'd appreciate any suggestions)

@ocombe
Copy link
Owner

ocombe commented Jun 17, 2014

That's a clever way to do this ! I wonder how I could include this into ocLazyLoad to simplify the process, maybe with a function that would return a template by name once it's lazy loaded, and returns a promise in the mean time.

@ocombe
Copy link
Owner

ocombe commented Jun 17, 2014

As for your original issue @amcdnl is it possible to get a copy of the files to debug it ? Maybe a plunkr, or a zip at olivier.combe@gmail.com ?

@amcdnl
Copy link
Author

amcdnl commented Jun 17, 2014

I ended up doing this:

      load: function($ocLazyLoad) {
                return $ocLazyLoad.load({
                    name: 'search', 
                    files: ['app/search/search']
                },{
                    name: 'search.list', 
                    files: ['app/search/list/list']
                });
            }

@ocombe
Copy link
Owner

ocombe commented Jun 17, 2014

Ok so this is closed ? By the way you can use the param debug: true when you configure the ocLazyLoadProvider to print the errors to the console (see the readme), it might help

@amcdnl
Copy link
Author

amcdnl commented Jun 17, 2014

No, not yet. The original issue still happens in the latest code set but not after the commit I started above.

@ocombe
Copy link
Owner

ocombe commented Jun 17, 2014

Well, then is it possible to get a copy of the files to debug it ? Maybe a plunkr, or a zip at olivier.combe@gmail.com ? Otherwhise it will be hard to find the source of the problem :(

@amcdnl
Copy link
Author

amcdnl commented Jun 17, 2014

Ya, I'll try to make a plunker for ya this afternoon.

@gilbox
Copy link

gilbox commented Jun 18, 2014

@ocombe I was thinking about your idea of making it even more integrated. It turns out uiRouter has an extremely powerful decorator method. It allows us to define our states simply like this:

    $stateProvider
      .state('lazy', {
        url: "/lazy",
        lazyModule: 'app.lazy',
        lazyFiles: 'lazy',
        lazyTemplateUrl: 'lazy.html',
        controller: 'lazyCtrl'
      });

This should work with explicit views (you can define the lazy__ properties in the view object) although I haven't actually tested it.

See the plunk

@amcdnl
Copy link
Author

amcdnl commented Jun 18, 2014

What are you guys thoughts on something like this: https://gist.github.com/amcdnl/9900479

@ocombe
Copy link
Owner

ocombe commented Jun 18, 2014

It looks fine but be careful with angular.module, it will throw an error if the module doesn't exists

@amcdnl
Copy link
Author

amcdnl commented Jun 18, 2014

Ya, some better error checking and maybe a manual option would make it pretty useful.

@amcdnl
Copy link
Author

amcdnl commented Jun 23, 2014

@ocombe - sorry no idea what i was doing wrong but after fully blowing my app out w/ the previous version i started to make a plunker this morning and when upgraded my solution it works this time :).

I did notice 0.3.0 loads things faster feeling, you notice this?

@amcdnl amcdnl closed this as completed Jun 23, 2014
@ocombe
Copy link
Owner

ocombe commented Jun 23, 2014

I did a bit of refractoring/optimizing so it's quite possible yes, but I'm not sure if it should be that perceptible.
Glad to know that you've sorted it out.

@amcdnl amcdnl reopened this Jul 11, 2014
@amcdnl
Copy link
Author

amcdnl commented Jul 11, 2014

Actually this is still a problem, the reason I thought it was resolved is because I changed my structure but upon doing a refactor to make it more modular it fails. The issue essentially is in the above scenario the controller is never init'd but it is loaded okay.

This is such a hard example to duplicate I'm not sure it would be possible to in a simple plunker though.

@ocombe ocombe closed this as completed in 91ed522 Jul 14, 2014
@ocombe
Copy link
Owner

ocombe commented Jul 14, 2014

Thanks again @amcdnl for your persistence, it should be fixed in 0.3.1 !

@amcdnl
Copy link
Author

amcdnl commented Jul 15, 2014

Thanks!!! When I try to use bower to pull your project I get the following: http://www.screencast.com/t/rgSEWlPGuiZ I never get this with any other bower packages, any ideas?

@ocombe
Copy link
Owner

ocombe commented Jul 15, 2014

https://twitter.com/bower/status/487704111832252417
Try "bower cache clean and update to Bower 1.3.8."

@amcdnl
Copy link
Author

amcdnl commented Jul 15, 2014

Ah yes ... found it after I posted this hehe

@amcdnl
Copy link
Author

amcdnl commented Jul 15, 2014

Your change works! ThankS!

@nithinprasad
Copy link

Hi am trying to lazy load controller definition when a particular state has been reached

.state('menu.table', {
            url: '/table',
            controller: 'tableController',
            templateUrl: 'module/table/table.html',
            resolve :{
                loadMyCtrl : ['$ocLazyLoad',function($ocLazyLoad){
                    return $ocLazyLoad.load({
                        name:"smartExpenseApp.tableController",
                        files:["module/table/js/table.js"]
                    });
                }

                ]
            }
        })

when going to that state it is loading that file

my table.js is

smartExpenseApp.controller('tableController',function ($scope, $log) {
    $scope.names = [
        {
            name: 'Jani'
            , country: 'Norway'
        }
        , {
            name: 'Carl'
            , country: 'Sweden'
        }
        , {
            name: 'Margareth'
            , country: 'England'
        }
        , {
            name: 'Hege'
            , country: 'Norway'
        }
        , {
            name: 'Joe'
            , country: 'Denmark'
        }
        , {
            name: 'Gustav'
            , country: 'Sweden'
        }
        , {
            name: 'Birgit'
            , country: 'Denmark'
        }
        , {
            name: 'Mary'
            , country: 'England'
        }
        , {
            name: 'Kai'
            , country: 'Norway'
        }
  ];

    $scope.sortField = "name";
    $scope.sortBy = false;
    $scope.sortColumn = function (column) {
        $scope.sortField = column;
        $scope.sortBy = $scope.sortField == (column) ? !$scope.sortBy : false;

    }
    $scope.getSortClass = function (column) {
        if ($scope.sortField == column) {
            return $scope.sortBy ? "glyphicon glyphicon-triangle-bottom" : "glyphicon glyphicon-triangle-top";
        }

        return 'glyphicon glyphicon-minus-sign';
    }
});

but I am getting error

tableController is not defined

@ocombe
Copy link
Owner

ocombe commented Apr 8, 2016

Hello,

change smartExpenseApp.controller(... to angular.module('nameOfYourModule').controller(...

@nithinprasad
Copy link

It has solved my undefined problem but the value that i have defined under the controller is not reflecting in the html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants