angular: router.navigateUrl('/') -- > zone.js drainMicroTaskQueue running into endless loop

I’m submitting a…


[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

I am trying to do a simple router navigation on line 48 on app.component.ts.

When I do that the application goes into an infinite loop in zone.js. Tasks are cleared on line 598 but by the time line 602 is executed, _microTaskQueue again contains a task and this is an infinite loop that keeps on going.

Logout is being called by a simple (click) handler. <li><a (click)="logoutUser()">Logout</a></li>



app.component.ts

01	import {Component, OnInit} from "@angular/core";
02	import {GlobalService} from "./common/service/global.service";
03	import {Router} from "@angular/router";
04	import {EventHubService} from "./modules/event-emitter/event.emitter.service";
05	import {LoginComponent} from "./common/component/login/login.component";
06
07	@Component({
08		selector: 'app-root',
09		templateUrl: './app.component.html',
10		styleUrls: ['./app.component.css'],
11		providers: [GlobalService]
12	})
13	export class AppComponent implements OnInit
14	{
15		ngOnInit(): void
16		{
17			EventHubService.get(LoginComponent.LoginEvent)
18		}
19
20		title = 'My Company';
21		public  _loggedUserName = null;
22		public  _logginMethod : string;
23
24		constructor(private _router: Router,
25					private _gs : GlobalService)
26		{
27			var self = this;
28			EventHubService.get(LoginComponent.LoginEvent).subscribe(() => {
29				self.loginUser();
30			});
31		}
32
33		loginUser ()
34		{
35			if (GlobalService.userSession)
36			{
37				this._loggedUserName = GlobalService.userSession.displayName;
38				this._logginMethod = GlobalService.userSession.isAdLogin ? "Company" : GlobalService.userSession.companyGroup;
39			}
40		}
41
42		logoutUser()
43		{
44			this._gs.logOffUser();
45			this._loggedUserName = "";
46			this._logginMethod = "";
47
48			this._router.navigateByUrl('/');
49		}
50	}


zone.js

593	function drainMicroTaskQueue() {
594		if (!_isDrainingMicrotaskQueue) {
595			_isDrainingMicrotaskQueue = true;
596			while (_microTaskQueue.length) {
597				var queue = _microTaskQueue;
598				_microTaskQueue = [];
599				for (var i = 0; i < queue.length; i++) {
600					var task = queue[i];
601					try {
602						task.zone.runTask(task, null, null);
603					}
604					catch (error) {
605						_api.onUnhandledError(error);
606					}
607				}
608			}
609			var showError = !Zone[__symbol__('ignoreConsoleErrorUncaughtError')];
610			_api.microtaskDrainDone();
611			_isDrainingMicrotaskQueue = false;
612		}
613	}

Expected behavior

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


project.json:
{
  "name": "customer-support-center",
  "version": "0.0.0",
  "license": "Commercial",
  "angular-cli": {},
  "scripts": {
    "start": "ng serve",
    "lint": "tslint \"src/**/*.ts\"",
    "test": "ng test",
    "pree2e": "webdriver-manager update",
    "e2e": "protractor"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.3.6",
    "@angular/common": "^4.3.6",
    "@angular/compiler": "^4.3.6",
    "@angular/core": "^4.3.6",
    "@angular/forms": "^4.3.6",
    "@angular/http": "^4.3.6",
    "@angular/platform-browser": "^4.3.6",
    "@angular/platform-browser-dynamic": "^4.3.6",
    "@angular/router": "^4.3.6",
    "angular-2-local-storage": "^1.0.0",
    "angular2-cookie": "^1.2.6",
    "angular2-datatable": "^0.6.0",
    "angular2-jwt": "^0.2.3",
    "angular2-ladda": "^1.1.1",
    "angular2-modal": "^3.0.3",
    "angular2localization": "^1.4.1",
    "bootstrap-checkbox": "^1.4.0",
    "core-js": "^2.5.1",
    "lodash": "^4.17.4",
    "ng2-recaptcha": "^1.7.0",
    "ng2-sidebar": "^1.8.2",
    "ng2-validation": "^4.2.0",
    "rxjs": "^5.4.3",
    "ts-helpers": "^1.1.1",
    "zone.js": "^0.8.17"
  },
  "devDependencies": {
    "@angular/cli": "^1.3.2",
    "@angular/compiler-cli": "^4.3.6",
    "@types/jasmine": "^2.5.54",
    "@types/node": "^8.0.26",
    "codelyzer": "^3.1.2",
    "jasmine-core": "^2.8.0",
    "jasmine-spec-reporter": "^4.2.1",
    "karma": "^1.7.1",
    "karma-chrome-launcher": "^2.2.0",
    "karma-cli": "^1.0.1",
    "karma-jasmine": "^1.0.2",
    "karma-remap-istanbul": "^0.6.0",
    "protractor": "^5.1.2",
    "ts-node": "^3.3.0",
    "tslint": "^5.7.0",
    "typescript": "^2.5.2",
    "webdriver-manager": "^12.0.6"
  }
}

Browser:
- [X] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: 6.10.2
- Platform:  Windows

Others:

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 16 (6 by maintainers)

Most upvoted comments

We got it working, Angular5 was decoding url and which was read by angular 1 and it is updating with encoded url, which triggers infinite call for angular 1 router.

so currently overrides default UrlSerializer and it worked.

import {UrlSerializer, UrlTree, DefaultUrlSerializer} from ‘@angular/router’;

export class CustomUrlSerializer implements UrlSerializer { parse(url: any): UrlTree { let dus = new DefaultUrlSerializer(); return dus.parse(url); }

serialize(tree: UrlTree): any {
    let dus = new DefaultUrlSerializer(),
        path = dus.serialize(tree);
    // use your regex to replace as per your requirement.
    console.log(path);
    path = path.replace('/md','%2Fmd');
    console.log(path);
    return path;
}

}

Thanks JiaLiPassion

-samyak