Navigation Menu

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

[Q] Conditional loading external module #147

Closed
alex88 opened this issue Mar 19, 2015 · 24 comments
Closed

[Q] Conditional loading external module #147

alex88 opened this issue Mar 19, 2015 · 24 comments

Comments

@alex88
Copy link

alex88 commented Mar 19, 2015

Hi,

I've an angular app that's loaded in all pages of my website. On just one page, I've to load another module as a dependency of my app since there's a directive on that page handled by this additional module.

I've 2 files, one with angular and all its dependencies (plus my app) and another with the secondary module.

At first I was trying this way (coffeescript):

try
  angular.module 'secondmodule'
  angular.module 'myapp', ['secondmodule']
catch
  angular.module 'myapp', []
end

But since during the parsing of the first file secondmodule is not defined it throws the exception.
Leaving just angular.module 'myapp', ['secondmodule'] works on the page where the second module is included (maybe the check of modules is done during the bootstrap so both files are loaded) but throws the exception in all the other pages.

I've then tried to leave just angular.module 'myapp', [] and in the run stage do:

$ocLazyLoad.load('secondmodule')

that doesn't throw any exception but the directive inside my app isn't catched by the second module.

Is it possible to do this with ocLazyLoad?

@ocombe
Copy link
Owner

ocombe commented Mar 19, 2015

Yes it is possible, that's the whole point of this lib.
What do you mean by the directive isn't catched?

@alex88
Copy link
Author

alex88 commented Mar 19, 2015

Let me give you an example:

<body ng-app="myapp">
  <div mydirective></div>
</body>

imagine that the mydirective is handled by the second module, I've tried these things:

angular.module 'myapp', ['secondmodule'] # Works
angular.module 'myapp', []               # Doesn't work (of course)
$ocLazyLoad.load('secondmodule')         # Doesn't work (it should?)

the problem with the first solution is that on other pages angular throws exception since the second module is not defined (as the file is not included).

What I'm expecting (or at least trying to) is that mydirective is correctly handled by the second module, so I've to find a way using ocLazyLoad to load that module inside myapp.

@ocombe
Copy link
Owner

ocombe commented Mar 19, 2015

if your directive is already in the DOM when you load the second module, it's the reason why it doesn't "work". You'll have to use $compile on your dom to make angular aware that this new directive exists.
The alternative is to use the directive from ocLazyLoad to wrap your lazy loaded directive (see the docs, it should be self explanatory).

As for the loading, it should be $ocLazyLoad.load('urlToYourFile.js') (or <div oc-lazy-load="urlToYourFile.js"> ..... </div> if you use the directive)

@alex88
Copy link
Author

alex88 commented Mar 19, 2015

And what if the file has already been included in the page (the js file), using just the module name is fine?

@alex88
Copy link
Author

alex88 commented Mar 19, 2015

Anyway the directive is no already in the dom since it's show inside a modal created after user interaction (so way after all the files are loaded and the app running)

@ocombe
Copy link
Owner

ocombe commented Mar 19, 2015

Yes you can give the module name if the file is already in the page.

@alex88
Copy link
Author

alex88 commented Mar 19, 2015

So having just $ocLazyLoad.load('module name') should already work fine if the element is not in dom and it's rendered later?

@ocombe
Copy link
Owner

ocombe commented Mar 19, 2015

Yes it should

@alex88
Copy link
Author

alex88 commented Mar 19, 2015

Ok let me see if I can provide a working example or it's something else in my app

@alex88
Copy link
Author

alex88 commented Mar 19, 2015

I've recreated the test cases:

http://plnkr.co/edit/EoreaII9Sd28TZTYj2N5 this one works fine (as it includes the second module directly)
http://plnkr.co/edit/bTsu2ic7H8QDchQxTQzj this one is the one that doesn't work since it's not included
http://plnkr.co/edit/kA8kl0oLpZYjchi35CnH this one uses ocLazyLoad to load the module during app run and the dom doesn't include the directive (it's loaded just when you click on the button)

is this how it should work?

@ocombe
Copy link
Owner

ocombe commented Mar 19, 2015

Ok got it.
The problem is the following: when the app is bootstrapped, ocLazyLoad list all existing modules and mark them as "registered", so that it will not try to load them later (because angular will register them by itself).
But in your case the second module is not loaded by angular (because not loaded by first module), but ocLazyLoad thinks it should not be registered because it was in the dom at bootstrap.

You should use ocLazyLoad to load the file, or include the file by yourself after bootstrap.

Here is the updated version: http://plnkr.co/edit/H1ipLnRMomm9m5zGBZaA?p=preview

@alex88
Copy link
Author

alex88 commented Mar 19, 2015

Problem is that I'm using rails asset pipeline so I don't know the js path from the javascript (since it gets minified and names includes hash after compilation). Maybe I can just use a global var written in the view file and read that from javascript but it sounds a bit hacky.

Anyway your component doesn't load modules inside another module? It shouldn't set as registered only the modules included in the module not those globally registered? Maybe I can include a modified version that forces the reload of the module

@ocombe
Copy link
Owner

ocombe commented Mar 19, 2015

Since 0.6 it gets all calls to angular.module prior to init, but I should discriminate registered modules based on the call to angular.bootstrap instead of all from angular.module.
I'll mark it as an enhancement to make.

@ocombe
Copy link
Owner

ocombe commented Mar 19, 2015

In the mean time you can use 0.5.x, it should work for you

@alex88
Copy link
Author

alex88 commented Mar 19, 2015

You mean without changing anything? Since I've just tried with 0.5.2 and it doesn't work

http://plnkr.co/edit/a40aPLnAR6UtX5QYDio9

@ocombe
Copy link
Owner

ocombe commented Mar 19, 2015

Ah yes, it throws an error "Unable to load secondmodule", I thought it should work, but I made a change in 0.6.2 to load modules based on name only (with no file), so that's why it won't work before.

Well I guess that you'll have to wait for my next release, it should get out before the end of the week if all goes according to plan (or at least I'll make a beta release). Is it ok ?

@alex88
Copy link
Author

alex88 commented Mar 19, 2015

Yeah sure that sounds great! It has a minimal impact for us, just an improvement do not have a fat js file for every page.

Thanks a lot!

@ocombe ocombe added bug and removed enhancement labels Mar 19, 2015
@ocombe ocombe added this to the 1.0 - Stable api & modularity milestone Mar 19, 2015
@ocombe ocombe closed this as completed in a9e6248 Mar 19, 2015
@ocombe
Copy link
Owner

ocombe commented Mar 19, 2015

Ok, you can try the 1.0.0-alpha1 that I just released

@alex88
Copy link
Author

alex88 commented May 29, 2015

@ocombe sorry for the delay, my situation is still the same. I've 2 files, one for my app and another one that declares an additional module.
I want that during app run, the secondary module is loaded if it has been declared (included) in page.

In my previous example http://plnkr.co/edit/kA8kl0oLpZYjchi35CnH it still doesn't work, the directive from the module lazy loaded still isn't rendered. Should it be used in another way?

@ocombe
Copy link
Owner

ocombe commented May 29, 2015

I fixed your plunkr:
http://plnkr.co/edit/g8GJBedzLddNjdoXChDh?p=preview

You were loading secondmodule instead of secondmodule.js:

$ocLazyLoad.load('secondmodule.js');

Now it works fine.

But there's still a bug, it should have thrown an error when it didn't find an extension for secondmodule, instead it was not loading the file and saying the everything was ok...

I'm reopening this until I fix this "bug".

@ocombe ocombe reopened this May 29, 2015
@alex88
Copy link
Author

alex88 commented May 29, 2015

@ocombe not what I want, look at this plunkr:
http://plnkr.co/edit/kLljp4NlgpZU0p9zcf4z

as I said before, the js is already loaded by the html, angular module is already defined in the angular namespace, I just want to load it into my app after initialisation. This because the secondary file is loaded in some pages and in other it's not.

@ocombe
Copy link
Owner

ocombe commented May 29, 2015

Ok, I got it working but you'll need to use inject instead of load (since the file is already loaded). I updated the plunkr: http://plnkr.co/edit/POOX4E4dCOLpidR5bnu9?p=preview
But, I need to release the fix for #171 before, I'll do that now.

@alex88
Copy link
Author

alex88 commented May 29, 2015

Great, I'll tell you how it works as soon as #171 is fixed

@ocombe ocombe closed this as completed in 3159547 May 29, 2015
@ocombe
Copy link
Owner

ocombe commented May 29, 2015

Ok you can try the latest file from master :)

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

No branches or pull requests

2 participants