Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(router): routerLinkActive should not throw when not initialized #13273

Closed
wants to merge 2 commits into from

Conversation

DzmitryShylovich
Copy link
Contributor

@DzmitryShylovich DzmitryShylovich commented Dec 6, 2016

Fixes #13270

Also quickly describe what this PR fixes

if we have a template with only interpolation it works fine:

<div routerLinkActive="active" #rlaDashboard="routerLinkActive"> 
    <a routerLink="/dashboard">
      Dashboard isActive: {{rlaDashboard.isActive}}
    </a>
  </div>

but if we have bindings it fails:

<div routerLinkActive="active" #rlaTest="routerLinkActive"> 
    <a routerLink="/test">
    </a>
    <span *ngIf="rlaTest.isActive">DOES NOT WORK </span>
     or
   <span [ngClass]="{'highlight':rlaTest.isActive}">DOES NOT WORK </span>
  </div>

Getter is called before ContentChildren is initialized thus it failed here with the error Cannot read property some of undefined

@DzmitryShylovich DzmitryShylovich changed the title fix(router): routerLinkActive active should not throw when not initia… fix(router): routerLinkActiveshould not throw when not initialized Dec 6, 2016
@DzmitryShylovich DzmitryShylovich changed the title fix(router): routerLinkActiveshould not throw when not initialized fix(router): routerLinkActive should not throw when not initialized Dec 6, 2016
@vicb vicb added area: router action: review The PR is still awaiting reviews from at least one requested reviewer labels Dec 6, 2016
@@ -1959,6 +1959,7 @@ describe('Integration', () => {
@Component({
template: `<a routerLink="/team" routerLinkActive #rla="routerLinkActive"></a>
<p>{{rla.isActive}}</p>
<span *ngIf="rla.isActive"></span>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing a .not.toThrow() somewhere ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do u think it makes sense to assert that component creation doesn't throw an error?

expect(() => f = TestBed.createComponent(ComponentWithRouterLink)).not.toThrow();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do u think it makes sense to assert that component creation doesn't throw an error?

If it used to throw yes, otherwise no

@@ -89,46 +89,50 @@ export class RouterLinkActive implements OnChanges,

private classes: string[] = [];
private subscription: Subscription;
private _isActive: boolean = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isActive for consistency

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make all other private prop start with _ then please

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can rename it to something without underscore.
state, active?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whatever sounds best for you and you feel describes it best


ngAfterContentInit(): void {
this.links.changes.subscribe(s => this.update());
this.linksWithHrefs.changes.subscribe(s => this.update());
this.links.changes.subscribe(() => this.update());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_ =>

@vicb
Copy link
Contributor

vicb commented Dec 6, 2016

Please split the changes into 2 commits:

  • a refactor,
  • a fix

Also quickly describe what this PR fixes, add a unit test.

Thanks

@vicb vicb added the action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews label Dec 6, 2016
@vicb
Copy link
Contributor

vicb commented Dec 7, 2016

Please re-arrange in 1 refactor + 1 fix before it can be reviewed & merged

} else {
this.classes = data.split(' ');
}
this.classes = (Array.isArray(data) ? data : data.split(' ')).filter(c => !!c);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const classes = Array.isArray(data) ? data : data.split(' ');
this classes = classes.filter(c=> c);

@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {AfterContentInit, ContentChildren, Directive, ElementRef, Input, OnChanges, OnDestroy, QueryList, Renderer} from '@angular/core';
import {AfterContentInit, ChangeDetectorRef, ContentChildren, Directive, ElementRef, Input, OnChanges, OnDestroy, QueryList, Renderer} from '@angular/core';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to 2nd commit (.d.ts as well)

@@ -118,13 +121,15 @@ export class RouterLinkActive implements OnChanges,

private update(): void {
if (!this.links || !this.linksWithHrefs || !this.router.navigated) return;

const isActive = this.hasActiveLink();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const hasActiveLinks() ? (also add "s" on the method name)

this.active = isActive;
this.classes.forEach(
c => this.renderer.setElementClass(this.element.nativeElement, c, isActive));
this.cdr.detectChanges();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you actually detectChanges here ?

Copy link
Contributor Author

@DzmitryShylovich DzmitryShylovich Dec 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise it throws Expression ___ has changed after it was checked. We change get isActive() inside ngOnChanges which is forbidden without the second cycle of change detection. And I tried almost everything to avoid it but without any success.

One of the reasons why a separate directive was a bad idea.

@DzmitryShylovich
Copy link
Contributor Author

DzmitryShylovich commented Jan 6, 2017

@vicb ready for review

@jelbourn
Copy link
Member

@vicb can you re-review? This fix is important for material.

@vicb vicb added action: merge The PR is ready for merge by the caretaker pr_state: LGTM and removed action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews action: review The PR is still awaiting reviews from at least one requested reviewer labels Jan 17, 2017
@mhevery
Copy link
Contributor

mhevery commented Jan 18, 2017

@vicb vicb mentioned this pull request Jan 18, 2017
@mhevery mhevery closed this in 1a92e3d Jan 18, 2017
@DzmitryShylovich DzmitryShylovich deleted the gh/13270 branch January 18, 2017 07:10
mhevery pushed a commit that referenced this pull request Jan 19, 2017
wKoza pushed a commit to wKoza/angular that referenced this pull request Feb 12, 2017
juleskremer pushed a commit to juleskremer/angular that referenced this pull request Aug 28, 2017
juleskremer pushed a commit to juleskremer/angular that referenced this pull request Aug 28, 2017
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 10, 2019
idlechara pushed a commit to idlechara/angular that referenced this pull request Apr 27, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: router cla: yes hotlist: components team Related to Angular CDK or Angular Material
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] Template vars in conditional expressions don't work
5 participants