Call component's method in another component

Viewed 15

After clicking button I need to call the method 'exportHistoryToCSV' in this component, which calls method from another component. But I have an error.

    @UntilDestroy()
@Component({
  selector: 'device-form',
  templateUrl: './form.component.html',
  styleUrls: ['./form.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DeviceFormComponent implements OnInit, EditorComponent {
  @ViewChild('deviceHistoryComponent')
  deviceHistory!: DeviceHistoryComponent;

  constructor() {}

  ngOnInit() {
  }

  exportHistoryToCSV() {
    this.deviceHistory.exportToCSV();
  }
}

Method 'exportToCSV' in another component

      exportToCSV() {
    this.historyStore.exportHistoryToCsvFile();
  }

Error:

  core.mjs:7640 ERROR TypeError: Cannot read properties of undefined (reading 'exportToCSV')
    at DeviceFormComponent.exportHistoryToCSV (device-form.component.ts:59:24)
    at DeviceFormComponent_div_1_button_5_Template_button_click_0_listener (template.html:10:63)
    at executeListenerWithErrorHandling (core.mjs:15778:16)
    at wrapListenerIn_markDirtyAndPreventDefault (core.mjs:15813:22)
    at HTMLButtonElement.<anonymous> (platform-browser.mjs:459:38)
    at _ZoneDelegate.invokeTask (zone.js:406:31)
    at Object.onInvokeTask (core.mjs:26365:33)
    at _ZoneDelegate.invokeTask (zone.js:405:60)
    at Zone.runTask (zone.js:178:47)
    at ZoneTask.invokeTask [as invoke] (zone.js:487:34)
handleError @ core.mjs:7640
handleError @ core.mjs:13387
executeListenerWithErrorHandling @ core.mjs:15781
wrapListenerIn_markDirtyAndPreventDefault @ core.mjs:15813
(anonimowa) @ platform-browser.mjs:459
invokeTask @ zone.js:406
onInvokeTask @ core.mjs:26365
invokeTask @ zone.js:405
runTask @ zone.js:178
invokeTask @ zone.js:487
invokeTask @ zone.js:1661
globalCallback @ zone.js:1692
globalZoneAwareCallback @ zone.js:1725
1 Answers

Make sure your other component is in the DeviceFormComponent DOM, otherwise, you'll get the undefined error message. Take a look at this example:

<h1>Parent Component</h1>
<button (click)="onClick()">Call Another Component</button>
<app-another-component></app-another-component>
@Component({...})
export class ParentComponent {
 @ViewChild(AnotherComponent) anotherOne!: AnotherComponent;

 onClick(): void {
   this.anotherOne.sayHello();
 } 
}

AnotherComponent

@Component({...})
export class AnotherComponent {
  sayHello(): void {
    console.log('Greetings from Another Component');
  }
}

If you wanna know more about ViewChild, I recommend reading the docs

Related