Reputation: 31275
Note: since the problem is a little complex, the code is abstracted for readability
We've a <parent-component>
like this:
<child-component></child-component>
<button (click)="doSomeClick()"> Do Some Click </button>
The template
of the <child-component>
is:
<textarea #childComponentElement #someField="ngModel" name="someName" [(ngModel)]="someModel"></textarea>
We're trying to access the value of this element inside the parent-component.component.ts
like this:
export class ParentComponent implements AfterViewInit {
@ViewChild('childComponentElement') el:ElementRef;
ngAfterViewInit() {
console.log(this.el.nativeElement.value);
}
doSomeClick(){
}
}
However it throws this error:
Cannot read property 'nativeElement' of undefined
What have we tried so far:
<parent-component>
, we need <textarea>
of <child-component>
angular-tree-component
ElementRef
seems to be an old thingthis.element.nativeElement
& <input>
element is getting established?*ngIf
used with #childComponentElement
ngAfterViewInit
onlyUpvotes: 2
Views: 818
Reputation: 9136
There's no easy way to this with a nested component, you'll have to create an EventEmitter
that emits the ElementRef
of the element you are trying to get access to:
child.component.ts
class ChildComponent implements AfterViewInit {
@Output()
templateLoaded: EventEmitter<ElementRef> = new EventEmitter()
@ViewChild('childComponentElement') el: ElementRef
ngAfterViewInit(): void {
this.templateLoaded.emit(this.el)
}
}
parent.component.html
<child-component (templateLoaded)="templateLoaded($event)"
parent.component.ts
class ParentComponent {
templateLoaded(template: ElementRef): void {
// do stuff with the `template`
}
}
Original Answer
Try using the read
property in the 2nd parameter of ViewChild
@ViewChild('childComponentElement', {read: ElementRef}) el: ElementRef
If you are wondering about the second parameter, this answer gives a very good explanation: What is the read parameter in @ViewChild for
Upvotes: 4
Reputation: 6942
Use the @Output
decorator or a service instead of trying hopelessly to access the textarea directly from the parent component
child template
<textarea #childComponentElement #someField="ngModel" name="someName" [(ngModel)]="someModel"></textarea>
child component
@ViewChild('childComponentElement') el:ElementRef;
@Output() textarea = new EventEmitter();
constructor(){
this.textarea.emit(this.el.nativeElement.value);
}
parent template
<child-component (change)="getdata($event)"></child-component>
parent component
export class ParentComponent {
getdata(e) {
console.log(e);
}
}
Upvotes: 1