1

I am trying to hide the other links when one of the link is clicked, I have tried using "Viewchild" in the component to get access to the name attribute of the anchor tag. Please find the below code in the component.

import { Component, ElementRef, ViewChild } from '@angular/core';


@Component({
    selector: 'my-app',
    template: `<h1>My First Angular App</h1>
<div style="float:right;">
               <a routerLink="First" *ngIf="!isOn" (click)="setState(first)"  let name="first">First</a> |
               <a routerLink="Second" *ngIf="!isOn" (click)="setState(second)" let name="second">Second</a> |
               <a routerLink="Third" *ngIf="!isOn" (click)="setState(third)" let name="third">Third</a> |
               <a routerLink="Fourth" *ngIf="!isOn" (click)="setState(fourth)" let name="fourth">Fourth</a> 
</div>
<br/>
<div>
<router-outlet></router-outlet>
</div>
`
})
export class AppComponent {


    private isOn: boolean = false;
    private trst: string;


    @ViewChild('name') input3: ElementRef;


    ngAfterViewInit() {
        console.log(this.input3.nativeElement); 
    }

    setState(e: any): void {

        var native = this.input3.nativeElement;  //throws error here

        var myattr = native.getAttribute("input3");
        alert("my attribute value is from click : " + myattr);    

         this.trst = this.input3.nativeElement.value;  
         alert(this.trst);
         alert(e);

        if (this.trst == e)
        {
            this.isOn = false;
        }
        else
        {
            this.isOn = true;
        }
    }

}

What is wrong with above code accessing the element with viewchild, is there any other way where I can access the name attribute value of anchor tag?

I tried following the below link to fix , but had no luck in resolving the issue

@viewChild not working - cannot read property nativeElement of undefined

Community
  • 1
  • 1
Sravan Dudyalu
  • 185
  • 3
  • 15
  • you need to refer by id.. where is the id set in your html ? – Suraj Rao Mar 05 '17 at 09:48
  • Also, where is setState called? Make sure it is only called after viewInit. – EluciusFTW Mar 05 '17 at 09:51
  • Why do you need access to the native element in the first place? There is most probably a much better solution than accessing dom elements. What are you trying to achieve? – JB Nizet Mar 05 '17 at 09:52
  • Another simple alternative method is here in this [**answer**](http://stackoverflow.com/questions/42542782/get-the-width-height-and-offset-of-clicked-div-angular-2) – Aravind Mar 05 '17 at 09:54
  • You don't need it to get the state of the element which should be programmed. – Roman C Mar 05 '17 at 10:19

1 Answers1

2

I can see a few things wrong with your code. For starters, you should use #name="first" in your anchor tags instead of let name="first". But then you have multiple ViewChildren with the same name and it still won't work.

Accessing raw DOM elements probably isn't the answer here. I'd rather do something like this:

import { Component, ElementRef, ViewChild } from '@angular/core';

@Component({
    selector: 'my-app',
    template: `<h1>My First Angular App</h1>
<div style="float:right;">
               <a routerLink="First" *ngIf="isSelected('first')" (click)="setState('first')">First</a> |
               <a routerLink="Second" *ngIf="isSelected('second')" (click)="setState('second')">Second</a> |
               <a routerLink="Third" *ngIf="isSelected('third')" (click)="setState('third')">Third</a> |
               <a routerLink="Fourth" *ngIf="isSelected('fourth')" (click)="setState('fourth')">Fourth</a> 
</div>
<br/>
<div>
<router-outlet></router-outlet>
</div>
`
})
export class AppComponent {
    private selectedLink: string;

    setState(e: string): void {
        this.selectedLink = e;
    }

    isSelected(name: string): boolean {
        if (!this.selectedLink) { // if no link is selected, always return true so everything is shown
            return true;
        }

        return (this.selectedLink === name); // if current link is selected, return true, else return false
    }
}
Brother Woodrow
  • 6,092
  • 3
  • 18
  • 20
  • Thanks @Brother Woodrow, This is what I was looking for. Although I heard, declaring a variable with "#" has been deprecated in the latest release and instead "'let" is used to do the job, correct me if I am wrong. – Sravan Dudyalu Mar 05 '17 at 13:21