ocombe / ocLazyLoad

Lazy load modules & components in AngularJS
https://oclazyload.readme.io
MIT License
2.63k stars 509 forks source link

ocLazyLoad + ui-router = page refresh problem #196

Open Falci opened 9 years ago

Falci commented 9 years ago

At first, not sure if this problem can be solved in ocLazyLoad (maybe is a question for ui-router)

I have an app that uses ocLazyLoad to load an external file, as described here

The loaded file has some new routes. When user goes to this page and tries refresh the page I have a problem: When the app is reloaded under an URL of an external module/file, ui-router says: there is no state for this URL (because ocLazyLoad doesn't finished the load yet) and sends user to default page (otherwise)

This community was very helpful in my last question (thanks again) maybe someone has faced this problem.

ocombe commented 9 years ago

Are you loading the new routes using ui-router future states ?

ocombe commented 9 years ago

I haven't done this myself, but you might be able to achieve this with http://christopherthielen.github.io/ui-router-extras/#/future (and an old article about this: http://bardo.io/2014/08/26/oclazyload-future-states/, be careful the ocLazyLoad api has changed a bit since this has been written, but the main idea remains)

Falci commented 9 years ago

No, I'm not.

The main module (app.js) needs to know all URL from modules that will be loaded by ocLazyLoad?

ocombe commented 9 years ago

No idea, I have never used it, but looks like it does yes. You can ask @kbdaitch, he's the one who wrote the article :)

charandas commented 9 years ago

@Falci You cannot have new routes register with ui-router lazily unless you use ui-router-extras or a similar mechanism. Basically the extras package builds upon ui-router stateNotFound feature to lazily define the new routes.

Many newer seed projects are using the extras package, including this one, so I recommend it.

Yes, ocLazyLoad can lazily load any modules, but you need the aforementioned integration to make it work with ui-router routing.

Falci commented 9 years ago

I'm trying to use $urlRouterProvider.otherwise() with a function that return true and wait for $ocLazyLoad.inject() to continue..

Now I can prevent the ui-route to send the user to otherwise page, but how to resolve the actual URL to a state and trigger $state.go()?

charandas commented 9 years ago

@Falci in my experience, I have found that you cannot trick ui-router. It needs to happen as mentioned in my previous comment. Other than that, it's not an ocLazyLoad issue.

alleypa commented 8 years ago

How do you solve the problem with Oclazyload + UI.router and implementing nested views. On every refresh the parent controller is always crashing. Something like the below. Any suggestion will be highly appreciated.

Error: [ng:areq] Argument 'PtpController' is not a function, got undefined http://errors.angularjs.org/1.2.29/ng/areq?p0=PtpController&p1=not%20aNaNunction%2C%20got%20undefined at http://localhost:9009/vendor/angular/angular.js:78:12 at assertArg (http://localhost:9009/vendor/angular/angular.js:1511:11)

charandas commented 8 years ago

I have had nested views work for me in the past, but I didn't implement lazy loading a whole hierarchy in those use cases. Instead, I defined a requirejs/angular module that defined a whole hierarchy for a feature. Once, I detected that the user wants to access that feature in the app, I just used ocLazyLoad to load the aforementioned requirejs module, and the nesting of all the states works as usual from there on, meaning no difference is to be found between its working and a non-lazily loaded module.

@alleypa Unfortunately, I haven't touched angular in a while, so won't be able to debug your code, but hope this helps.

alleypa commented 8 years ago

@charandas Many thanks for getting back. I will love to how you've implemented your solution. Can you mighty PLEASE dig out some of your sample code for me? Hoping to here back from you.

@ocombe do you have an opinion on how this could be solved using ui.router nested views with oclazy load.

knvpk commented 8 years ago

Hi @alleypa , im facing the same issue, if you found a solution please let me know, At first i thought it is minification problem and set the uglification to not mangle the $q and $ocLazyLoad as mentioned in this (repo)[https://github.com/voidberg/webpack-angularjs-lazyload#issues] but the problem still exists.

alleypa commented 8 years ago

Hi @pavankumarkatakam , I reorganised our app not to use nested views. At least for now our implementation works without nested view. What I can also suggest is to set the 'serie' as indicated here https://oclazyload.readme.io/docs/oclazyload-service. This will ensure all the files you want lazy loaded are loaded in sequential order. Always but your '.*module.js' at the top (first). Let me know if this helps.

knvpk commented 8 years ago

Hi @alleypa, thanks for the reply. The problem is coming some times ans some times it is working well I want to check it so many hours to say it is resolved or not.

ocombe commented 8 years ago

Also if you use nested states, you can inject a parent (or sibling) resolve into another to make sure they are resolved in order (each resolve is in fact something that you can inject, much like any other component, service, ...)

alleypa commented 8 years ago

@pavankumarkatakam, another thing to look at is your chrome extensions if you use any. We found that they tend to hinder on oclazy load performance when lazy loading files/components. Remove all of them and add them back one after the other until you find the culprit extension. Most times we get this behaviour when we have developer tools open. Also check the behaviour with the 3 main browsers ( IE, Chrome, Firefox)

knvpk commented 8 years ago

Thanks @ocombe and @alleypa , for more information. I will check it and reply to you members. Hi @ocombe , please give me an example for injecting the parent resole to child because im using more than 3 nested states at many places.

ocombe commented 8 years ago

Something like that:

$stateProvider
  .state('contacts', {
    templateUrl: 'contacts.html',
    controller: '...',
    resolve: {
        myResolve1: function() { ... }
    }
  })
  .state('contacts.list', {
    templateUrl: 'contacts.list.html',
    resolve: {
        myResolve2: function(myResolve1) { ... }
    }
  });

You use the name of your resolve. In this case you can be sure that myResolve1 is completely resolved before it executes the resolve function myResolve2.

knvpk commented 8 years ago

Hi @ocombe , I will change all of my code to that and check it.

alleypa commented 8 years ago

Hi @pavankumarkatakam, do you have update improvements with your nested view implementation

knvpk commented 8 years ago

Hi @alleypa , As i said before it is totally working fine in the localhost development. So i changed the code as @ocombe and you said and uploaded the new one but error appearing some times. And when i examined deeply that the when module name something is required by the application which resides in the 36.js (it is webpack generated filename) but it is downloading 64.js so that the old files which is not deleted is colliding with the newly uploaded one, So i cleared the all the folder and uploaded the new build its working fine yesterday and today. I have learnt a lesson that code should be shipped with proper software and may be zero down time.