After enabling ivy in my angular project, everything compiles but when starting the app in the browser I get the following error during app bootstrap:
Error: Cannot instantiate cyclic dependency! ApplicationRef
at throwCyclicDependencyError (core.js:5208)
at R3Injector.push../node_modules/@angular/core/__ivy_ngcc__/fesm5/core.js.R3Injector.hydrate (core.js:11763)
at R3Injector.push../node_modules/@angular/core/__ivy_ngcc__/fesm5/core.js.R3Injector.get (core.js:11590)
at injectInjectorOnly (core.js:648)
at ɵɵinject (core.js:653)
at injectArgs (core.js:730)
at Object.factory (core.js:11858)
at R3Injector.push../node_modules/@angular/core/__ivy_ngcc__/fesm5/core.js.R3Injector.hydrate (core.js:11767)
at R3Injector.push../node_modules/@angular/core/__ivy_ngcc__/fesm5/core.js.R3Injector.get (core.js:11590)
at injectInjectorOnly (core.js:648)
I'm struggling to find out where the cyclic dependency is and why it works fine when not using ivy. I tried using madge (madge --circular --extensions ts ./) but no circular dependency's where found.
Edit: I've manually gone though all my services and verified that there is no cyclic dependency between them
A cyclic dependency is an indication of a design or modeling problem in your software. Although you can construct your object graph by using property injection, you will ignore the root cause and add another problem: property injection causes Temporal Coupling. Instead, the solution is to look at the design closely.
To reduce or eliminate circular dependencies, architects must implement loose component coupling and isolate failures. One approach is to use abstraction to break the dependency chain. To do this, you introduce an abstracted service interface that delivers underlying functionality without direct component coupling.
A cyclic dependency exists when a dependency of a service directly or indirectly depends on the service itself. For example, if UserService depends on EmployeeService , which also depends on UserService . Angular will have to instantiate EmployeeService to create UserService , which depends on UserService , itself.
Analyze cyclic dependenciesFrom the main menu, select Code | Analyze Code | Cyclic Dependencies. In the Specify Cyclic Dependency Analysis Scope dialog, select the scope of files that you want to analyze. Select the Include test sources option if you want to analyze your test code together with the production code.
Turns out that in my app.module providers I had a class with {provideIn: 'root'} in the @Injectable(), removing that fixed it.
providers: [
{ provide: ErrorHandler, useClass: AppErrorHandler }
]
Before
@Injectable({ providedIn: 'root' })
export class AppErrorHandler implements ErrorHandler {
After
@Injectable()
export class AppErrorHandler implements ErrorHandler {
I don't know why this wasn't a problem before ivy, even with AoT
You must be injecting the Router
somewhere in any of your services which uses @Injectable
. So you got two options:
Remove the dependency of router: Router
from your service constructor.
Upgrade to a minimum Angular 9.0.3 which fixes this issue of cyclic dependency.
(Got fixed in this MR https://github.com/angular/angular/pull/35642)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With