Comments (7)
OK, I think these were the same issue, and I have a solution.
The problem is that AngularJS supports "deferred bootstrap". This lets tools like Protractor set a flag on window.name
that causes AngularJS to defer finishing bootstrap until something calls angular.resumeBootstrap(extraModules)
. This allows these tools to insert their own debug modules into any AngularJS app without that app being aware of it.
Now, consider the recommended UI Router hybrid bootstrapping code:
platformBrowserDynamic().bootstrapModule(SampleAppModule).then(platformRef => {
const injector: Injector = platformRef.injector;
const upgrade = injector.get(UpgradeModule) as UpgradeModule;
upgrade.bootstrap(document.body, ['demo']);
const url: UrlService = injector.get(UrlService);
url.listen();
url.sync();
});
UrlService
has, indirectly, a dependency on $injector
, the AngularJS injector. Therefore, $injector
must be available to Angular before we try to get it. Angular's UpgradeModule installs an AngularJS module that captures the $injector
instance and provides it to Angular's DI system. Under normal circumstances, this module would be initialised immediately as part of the upgrade.bootstrap()
call.
However, because the AngularJS bootstrap is deferred, the call to upgrade.bootstrap()
will not cause bootstrapping to happen immediately. It will only happen at some indefinite future point, when Protractor (or whatever) calls angular.resumeBootstrap()
. This means that trying to get UrlRouter
straight afterward will fail, because the $injector
dependency has not been provided to Angular by the UpgradeModule yet.
My solution is to move the UrlService
initialisation into a run block of my app's AngularJS module. This ensures it will be run only when both the Angular and AngularJS parts of the hybrid app are ready. E.g.
myAngularJSModule.run(['$$angularInjector', ($$angularInjector) => {
const url: UrlService = $$angularInjector.get(UrlService);
url.listen();
url.sync();
}]);
$$angularInjector
is the Angular injector, which UpgradeModule makes available to the AngularJS DI system — the opposite of $injector
basically.
And now I'm going to lie down in a dark room for a while until my head stops hurting.
from angular-hybrid.
Ok, I managed to wrap the bootstrapping code with browser.ignoreSynchronization = true and set it to false when the test starts.
Its a workaround but it works
from angular-hybrid.
I'm seeing the same issue.
from angular-hybrid.
Actually, I think my issue may have been something different. I have raised it here: angular/protractor#4327
from angular-hybrid.
@jonrimmer Wow! gr8 work... when you get out of the dark room give yourself a pat on the back!
from angular-hybrid.
@jonrimmer You rock! Thanks!
from angular-hybrid.
Ran through this old answer as i was working on this same problem.
@artaommahe wrote a super helpful code snippet
I modified it to the following:
angular.element(document).ready(() => {
deferAndSyncUiRouter(angularJSAppModule); // angularjs module as a variable
platformBrowserDynamic()
// Manually bootstrap the Angular app
.bootstrapModule(AppModule) // Angular module imported from app.module.ts
.then(platformRef => bootstrapWithUiRouter(platformRef, angularJSAppModule));
});
export function deferAndSyncUiRouter(angularjsModule: ng.IModule): void {
angularjsModule
.config([ "$urlServiceProvider", ($urlService: UrlService) => $urlService.deferIntercept()])
.run(["$$angularInjector", $$angularInjector => {
const url: UrlService = getUIRouter($$angularInjector).urlService;
url.listen();
url.sync();
}]);
}
export function bootstrapWithUiRouter(platformRef: NgModuleRef<any>, angularjsModule: ng.IModule): void {
const injector = platformRef.injector;
const upgradeModule = injector.get(UpgradeModule);
upgradeModule.bootstrap(document.body, [ angularjsModule.name ]);
}
That got everything working for me.
Edit: Also you all may find these imports helpful for the top of your angularjs module file.
import * as angular from 'angular';
import {NgModuleRef} from "@angular/core";
import {getUIRouter} from '@uirouter/angular-hybrid';
import {UrlService} from '@uirouter/angular-hybrid/node_modules/@uirouter/angularjs'
import {UpgradeModule} from "@angular/upgrade/static";
import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
import {AppModule} from "./app.module";
from angular-hybrid.
Related Issues (20)
- Jest test suite failed to run AngularJS v1.x is not loaded! after upgrade from angular 7 to 9 HOT 6
- How to augment all routes with additional resolve using decorator HOT 2
- ui.router.upgrade' is not available! HOT 1
- Angular 9 - optimization: true breaks build HOT 1
- Version 12 causes "Unknown provider" on Angular states HOT 12
- Upgraded AngularJS component renders itself in ui-view HOT 1
- The target entry-point "@uirouter/angular-hybrid" has missing dependencies HOT 2
- Support for angular12 HOT 5
- UIViewNgUpgrade downgradedModule not specified HOT 1
- ngcc fails
- Angular 14 compatibility HOT 6
- Error bootstrapping AppModule Error: Cannot read properties of undefined (reading 'when') HOT 1
- Failure to inject $transition$ into a downgraded ng2 component HOT 9
- Angular 15 compatibility HOT 3
- After update to 15: UI router error TypeError: this.factory is undefined HOT 19
- random error: Cannot find module '@uirouter/angularjs' or its corresponding type declarations. HOT 3
- Add support for v16 in @uirouter/angular-hybrid HOT 3
- After update to v15.0.2 I get this error "Cannot read properties of undefined (reading 'inherit')"
- Wrong NATIVE_INJECTOR_TOKEN import HOT 2
- Add support for v17 in @uirouter/angular-hybrid HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from angular-hybrid.