Skip to content

Commit

Permalink
fix(router): routerLink support of null/undefined (angular#13380)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dzmitry Shylovich authored and hansl committed Dec 27, 2016
1 parent 9c69703 commit 174334d
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 14 deletions.
12 changes: 7 additions & 5 deletions modules/@angular/router/src/create_url_tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function createUrlTree(
}

function isMatrixParams(command: any): boolean {
return typeof command === 'object' && !command.outlets && !command.segmentPath;
return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
}

function tree(
Expand Down Expand Up @@ -70,7 +70,7 @@ class Navigation {
throw new Error('Root segment cannot have matrix parameters');
}

const cmdWithOutlet = commands.find(c => typeof c === 'object' && c.outlets);
const cmdWithOutlet = commands.find(c => typeof c === 'object' && c != null && c.outlets);
if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
throw new Error('{outlets:{}} has to be the last command');
}
Expand All @@ -91,7 +91,7 @@ function computeNavigation(commands: any[]): Navigation {
let isAbsolute = false;

const res: any[] = commands.reduce((res, cmd, cmdIdx) => {
if (typeof cmd === 'object') {
if (typeof cmd === 'object' && cmd != null) {
if (cmd.outlets) {
const outlets: {[k: string]: any} = {};
forEach(cmd.outlets, (commands: any, name: string) => {
Expand Down Expand Up @@ -169,7 +169,9 @@ function createPositionApplyingDoubleDots(
}

function getPath(command: any): any {
if (typeof command === 'object' && command.outlets) return command.outlets[PRIMARY_OUTLET];
if (typeof command === 'object' && command != null && command.outlets) {
return command.outlets[PRIMARY_OUTLET];
}
return `${command}`;
}

Expand Down Expand Up @@ -306,4 +308,4 @@ function stringify(params: {[key: string]: any}): {[key: string]: string} {

function compare(path: string, params: {[key: string]: any}, segment: UrlSegment): boolean {
return path == segment.path && shallowEqual(params, segment.parameters);
}
}
18 changes: 9 additions & 9 deletions modules/@angular/router/src/directives/router_link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ export class RouterLink {
}

@Input()
set routerLink(data: any[]|string) {
if (Array.isArray(data)) {
this.commands = data;
set routerLink(commands: any[]|string) {
if (commands != null) {
this.commands = Array.isArray(commands) ? commands : [commands];
} else {
this.commands = [data];
this.commands = [];
}
}

@HostListener('click', [])
@HostListener('click')
onClick(): boolean {
const extras = {
skipLocationChange: attrBoolValue(this.skipLocationChange),
Expand Down Expand Up @@ -163,11 +163,11 @@ export class RouterLinkWithHref implements OnChanges, OnDestroy {
}

@Input()
set routerLink(data: any[]|string) {
if (Array.isArray(data)) {
this.commands = data;
set routerLink(commands: any[]|string) {
if (commands != null) {
this.commands = Array.isArray(commands) ? commands : [commands];
} else {
this.commands = [data];
this.commands = [];
}
}

Expand Down
20 changes: 20 additions & 0 deletions modules/@angular/router/test/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,26 @@ describe('Integration', () => {
expect(native.getAttribute('href')).toEqual('/home');
}));

it('should not throw when commands is null', fakeAsync(() => {
@Component({
selector: 'someCmp',
template:
`<router-outlet></router-outlet><a [routerLink]="null">Link</a><button [routerLink]="null">Button</button>`
})
class CmpWithLink {
}

TestBed.configureTestingModule({declarations: [CmpWithLink]});
const router: Router = TestBed.get(Router);

let fixture: ComponentFixture<CmpWithLink> = createRoot(router, CmpWithLink);
router.resetConfig([{path: 'home', component: SimpleCmp}]);
const anchor = fixture.nativeElement.querySelector('a');
const button = fixture.nativeElement.querySelector('button');
expect(() => anchor.click()).not.toThrow();
expect(() => button.click()).not.toThrow();
}));

it('should update hrefs when query params or fragment change', fakeAsync(() => {

@Component({
Expand Down

0 comments on commit 174334d

Please sign in to comment.