2

I have had a look at this but it does not work -- maybe because the elements I am targeting are dynamically generated inside a custom component (<c-tabs>).

I have also had a look at this but this wouldn't work, I think, as i am not able to touch the custom component's code.

Relevant Elements enter image description here

HTML

<c-tabs #mainComponentTabs1 [items]="tabItems"></c-tabs>

I have tried the following ways to target it. None works.

Method 1. Using plain old Javascript:

ngAfterViewInit() {
    let att = document.createAttribute("id");
    att.value = "yada1";
    document.querySelectorAll(".c-tabs .hydrated")[0].setAttributeNode(att);
}

I have tried to have the above in the ngOnInit and ngOnViewInit methods but that didn't help. This method, oddly enough, works in the Chrome console window after the page has rendered. That is, the querySelected items get id attribute.

Method2. Using Angular's Renderer2. (Admittedly, I don't know how to get to the particular native elements that need the id's.

//first, declare target custom component element with viewchild:
export class MainComponent implements OnInit, AfterViewChecked, AfterViewInit {
    @ViewChild('mainComponentTabs1', { static: true }) c_tabs1: ElementRef;
    ...
    ngAfterViewChecked() {
        //neither of these approaches works.
        const c_tabs1El = this.c_tabs1.nativeElement;    
        this.renderer.setAttribute(c_tabs1El.items[0], 'id', 'dashboard-tab-link-search');

        const c_tabs1El2 = document.querySelectorAll("button.c-item");
        this.renderer.setAttribute(c_tabs1El2[0].nativeElement, 'id', 'dashboard-tab-link-dashboard');
      }
    ...
}

1 Answer 1

2

I'm not sure what elements are you trying to target, if you're trying to target the elements by class or tag but I think the following code will help you:

export class MainComponent implements OnInit, AfterViewChecked, AfterViewInit {
    // the static property must be true only if you are using it in ngOnInit
    @ViewChild('mainComponentTabs1', { static: false }) c_tabs1: ElementRef;
    ...
    ngAfterViewInit() {
        const targetElements = this.c_tabs1.nativeElement.querySelectorAll('button.c-item')

        targetELements.forEach((el, index) => this.renderer.setAttribute(el, 'id', `dashboard-tab-link-search-${index}`));
      }
    ...
}

Don't touch the DOM directly.

Sign up to request clarification or add additional context in comments.

3 Comments

this worked -- but only when i put this code in the ngAfterViewChecked() life-cycle method! TY!
@inonut-t Is there any good reason to use a local reference and ViewChild if we can target an element reliably with document.querySelector/All ?
@PakiPat using Document is not considered a good practice because are cases where no browser is available (for example doing server side rendering with Universal). The ElementRef and Renderer2 provides an abstraction for this kind of cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.