Home > Software design >  Angular: Cannot get ElementRef property
Angular: Cannot get ElementRef property

Time:02-16

I have the following code cloning this.child into obj in ngAfterViewInit method:

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

@Component({
  selector: 'child',
  template: `<input [value]="value">`,
})
export class ChildComponent {
  @Input() value: string;
}

@Component({
  selector: 'app-root',
  template: '<child [value]="value" #child></child>',
})
export class AppComponent {
  value = 'Some value';

  @ViewChild('child') child: ElementRef;

  ngAfterViewInit() {
    var obj: any = {};
    for (let prop in this.child)
      obj[prop] = (this.child as any)[prop];
    console.log('ngAfterViewInit', obj);
    // console.log('ngAfterViewInit', this.child.value); // but this line doesn't work!
  }
}

Please, see the source https://stackblitz.com/edit/angular-ivy-rhacx7?file=src/app/app.component.ts

It works fine and logged obj contains value property! But when I uncomment the last line of ngAfterViewInit method, it crashes with error: Property 'value' does not exist on type 'ElementRef'

I have tried this.child.nativeElement.value but this one leads to another error: Cannot read properties of undefined (reading 'value')

So, value property "does not exist in this.child" but it does exist in obj (a clone of the former!). Why is it so?

And why do I bother myself with "clone operations"? Because when I simply logged this.child into the console it did contain value property! I thought, maybe it was added after ngAfterViewInit but before logging to the console? That is why I copied the state of this.child that it had during ngAfterViewInit.

So, please, can somebody explain:

  1. Why does the linked code not work?
  2. Why view elements are not initialized with their input parameters before the moment ngAfterViewInit?

CodePudding user response:

That's because child is of type ChildComponent, not ElementRef:

working example

export class AppComponent {
  value = 'Some value';

  @ViewChild('child') child: ChildComponent;

  ngAfterViewInit() {
    var obj: any = {};
    for (let prop in this.child)
      obj[prop] = (this.child as any)[prop];
    console.log('ngAfterViewInit', obj);
    console.log('ngAfterViewInit', this.child.value);
  }
}

So that cloning of data isn't necessary, the value has been set, it's just that TypeScript was complaining that ElementRef doesn't have the property value, which it doesn't.

  • Related