Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Support asynchronous module.run() #4003

Closed
coli opened this issue Sep 13, 2013 · 62 comments
Closed

Support asynchronous module.run() #4003

coli opened this issue Sep 13, 2013 · 62 comments

Comments

@coli
Copy link

coli commented Sep 13, 2013

We want to issue a few $http calls in the module run block, ideally, the run should finish only after the $http and processing finishes before the dom compiling happens.

@petebacondarwin
Copy link
Contributor

This is not so easy but should be looked into.

@dagingaa
Copy link

The way Jasmine does this is by setting a flag, that will let the function run and wait for the callback until the flag is set to true, or until a timeout is fired.

Basically something like this:

var flag = false;
$http(...).success(flag = true);
$timeout(function () {
    flag = true;
    // Or add some error handling stuff here
}, 5000);
while (!flag) {};

It's not pretty, but should do the job. The code above isn't tested, so you may need to modify it a bit. It's getting late here. Hopefully something to get you by until something a bit prettier comes along.

@Narretz
Copy link
Contributor

Narretz commented Dec 18, 2013

+1

@coli
Copy link
Author

coli commented Dec 18, 2013

On a second though, this does lead to the inability to draw fancy loading screen using angular directives...

@bcherny
Copy link
Contributor

bcherny commented May 1, 2014

+1

@shahata
Copy link
Contributor

shahata commented May 1, 2014

Doesn't $routeProvider with resolve solve this? Maybe I didn't understand the problem...

@coli
Copy link
Author

coli commented May 1, 2014

This is more for async module init support. With that said, I no longer need this in my current projects.

@bcherny
Copy link
Contributor

bcherny commented May 2, 2014

@shahata $routeprovider does this, but not every use case for promise-giving runs uses routes. In my use case, it's for a module that wraps a directive and has nothing to do with routes.

@pocesar
Copy link
Contributor

pocesar commented Jun 1, 2014

+1

check if the run function returns a promise, then only procceed when it's resolved. since runBlocks is an array of functions, it shouldn't be hard at all

@horyd
Copy link

horyd commented Sep 11, 2014

+1

@davismj
Copy link

davismj commented Oct 23, 2014

+1 embarrassing that this got ignored

@pocesar
Copy link
Contributor

pocesar commented Oct 26, 2014

any idea when this is going to land? so frustrating to have to move initialization stuff to resolve in the router, mainly because sometimes the initialization code is url agnostic (aka, must be initialized for any type of URL that the user arrives at your SPA)

@davismj
Copy link

davismj commented Oct 26, 2014

i don't think angular will be receiving any enhancements henceforth. they're all being added to angular 2.0

@pocesar
Copy link
Contributor

pocesar commented Dec 6, 2014

how long the half-assed run method will remain synchronous? it's fine and understandable that config doesn't support asynchronous calls, since you don't have any providers that do $http calls, but run does. look the type of hacks that the lack of this feature (that should've been in since the beginning) causes
https://github.com/philippd/angular-deferred-bootstrap/blob/master/src/deferred-bootstrap.js

it's embarrassing

@cankayacan
Copy link

+1

@petebacondarwin
Copy link
Contributor

@btford is looking at how the use cases around this could be supported via the new router rather than inside run blocks.

@petebacondarwin petebacondarwin modified the milestones: 1.4.x, Backlog Dec 17, 2014
@edotassi
Copy link

+1

3 similar comments
@benzen
Copy link

benzen commented Dec 18, 2014

+1

@ziaukhan
Copy link

+1

@alexbeletsky
Copy link

+1

@petebacondarwin
Copy link
Contributor

The main problem we have is the $q is created inside a module that is being loaded when the runBlocks are being run. This means that we would need to somehow extract "some" of the services (or maybe modules) and create those first and then have a second pass that loads the rest of the modules (and services, run blocks, etc) after $q has been created.

@petebacondarwin
Copy link
Contributor

@lgalfaso - perhaps you could look into this a bit more as part of your $injector work later this week (or next)?

@fabiosussetto
Copy link

I know it's just a workaround, but I've normally solved the issue of having some async bootstrapping logic by using angular ui router and having a root abstract state in combination with resolve. The root abstract state has to be always resolved first, so it's a good place to load settings, display loading animations, etc.

@kashesandr
Copy link

+1

@vladmiller
Copy link

It's been two years since issue was opened and there is still no good solution

@petebacondarwin
Copy link
Contributor

@vladmiller There are solutions but perhaps you do not feel that they are good:

  • use ngRoute or ui-router with resolves and put your application startup code inside the top level route
  • create your own async bootstrap. see Support asynchronous module.run() #4003 (comment)
  • use the new component router with $onActivate in the top level component

Putting non-trivial application work inside .run blocks makes it difficult to unit test your code. So it is not something we want to encourage. Moving this to the Ice Box as something we are not likely to implement.

@petebacondarwin petebacondarwin modified the milestones: Ice Box, 1.5.x Mar 24, 2016
@vladmiller
Copy link

@petebacondarwin I would disagree with you; everyone expect angluar to be simple and intuitive, instead you have to either implement your own async bootstrap module or bootstrap module in different place. In my opinion this makes angular more complex.

Can you also explain what do you mean when saying that async code in .run will make testing more difficult?

Apologies for my previous rude comment.
Thanks

@pocesar
Copy link
Contributor

pocesar commented Mar 24, 2016

@petebacondarwin I fail to see how it makes it difficult to test. if you place the initialization code in a service, you can just watch/mock/compare the results you'll be expecting from the http backend mock, regardless if it's being executed inside a .run block or not. having code exist outside angular due to work-arounds for the lack of async run is what makes it almost impossible to test

@alexey-sh
Copy link

How it's going?

@petebacondarwin
Copy link
Contributor

Another approach: http://plnkr.co/edit/8XGSNOzzRGvgNSSnXx3M?p=preview

@vvmsoft
Copy link

vvmsoft commented Aug 25, 2016

@petebacondarwin solution worked for me

@petebacondarwin
Copy link
Contributor

Since there are workarounds and supporting async run blocks would add complexity to the bootstrap I don't think we will be implementing this feature.

@alexey-sh
Copy link

alexey-sh commented Sep 1, 2016

jfcfxekzl5m
Simple feature but too hard to implement. 😕

@yeluolei
Copy link

yeluolei commented Nov 2, 2016

+1 for this feature

@kevingilbert100
Copy link

+1

1 similar comment
@cristianhoyos66-zz
Copy link

+1

@cristianhoyos66-zz
Copy link

@petebacondarwin solution works good.

@canyetim
Copy link

canyetim commented Apr 3, 2017

+1. :(

@celiovasconcelos
Copy link

+1

3 similar comments
@rochejul
Copy link

+1

@liuhao2050
Copy link

+1

@nicolae-olariu
Copy link

+1

@petebacondarwin
Copy link
Contributor

We are not going to do this.

@Eduardo-Julio
Copy link

Eduardo-Julio commented Oct 2, 2017

+100, all the work arounds are terrible.

@angular angular locked and limited conversation to collaborators Oct 2, 2017
@petebacondarwin
Copy link
Contributor

@Eduardo-Julio - we are not going to implement this feature as it would make the bootstrap of AngularJS applications much more complex. Adding further +s will not help.

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

No branches or pull requests