0

I think this may be a duplicate question.

I have a component B in which there is a function saveContact(). I want to call this function from another function of component A .

So I

  1. Imported component B in component A. Then created a viewChild

  2. @ViewChild(ContactformComponent) contactForm: ContactformComponent;

  3. Called the function

    saveContactForm() { this.contactForm.saveContact(); }

When I run the application I get error TypeError: Cannot read property 'saveContact' of undefined. Can someone tell me what I am doing wrong.

Parent Component

import { ContactformComponent } from './forms/contactform/contactform.component';

@Component({
selector: 'app-insert',
templateUrl: './insert.component.html',
styleUrls: ['./insert.component.scss'],
animations: [routerTransition()]
})
export class InsertComponent implements OnInit {
@ViewChild(ContactformComponent) contactForm;

saveContactForm() {
this.contactForm.saveContact();
}
}

Child Component

@Component({
selector: 'app-contactform',
templateUrl: './contactform.component.html',
styleUrls: ['./contactform.component.scss']
})
export class ContactformComponent implements OnInit {
contactForm: FormGroup;

... // Form Code

  public saveContact() {
  const savedContact = {
  contactType: this.contactType,
  contactDescription: this.contactTypeDescription,
  contactSubType: this.contactSubType,
  contactSubTypeDescription: this.contactSubTypeDescription,
  referenceNumber: this.referenceNumber,
  lastVerifiedDate: this.parseDate(this.contactlastVerifiedDate.toString()),
  startDate: this.parseDate(this.contactStartDate.toString()),
  endDate: this.parseDate(this.contactEndDate.toString())
  };
  this.savedContact.emit(savedContact);
  this.snackbar.open('Contact Saved,Click on Create Customer or Fill more 
  Details', 'Close', {
  duration: 5000
  });
  }
Cpt Kitkat
  • 1,392
  • 4
  • 31
  • 50
  • The correct syntax is to use `@ViewChild('template-variable') contactForm: ContactformComponent;` where you need to use `template-variable` in your component HTML like this
    – Niladri May 13 '19 at 18:04
  • 3
    It will be better if you use services, because you create a service and that you can use everywhere. – TheCoderGuy May 13 '19 at 18:04
  • Is B a child of A ? – Franklin Pious May 13 '19 at 18:07
  • Using a service is also better if you want to call the function in multiple component, create a singleton instance and inject it in component. – Niladri May 13 '19 at 18:07
  • @Niladri Currently I am doing it the way it is mentioned in the approved answer https://stackoverflow.com/questions/45303683/angular-4-execute-function-from-another-component – Cpt Kitkat May 13 '19 at 18:12
  • @Ahmed, If B is not child of A, how do you use B in A? – nircraft May 13 '19 at 18:12
  • 1
    @Ahmed I was talking about the same to use a service – Niladri May 13 '19 at 18:13
  • Extremely sorry .. Yes B is child component of A – Cpt Kitkat May 13 '19 at 18:14
  • Do you really expect us to debug code we cannot see? – The Head Rush May 13 '19 at 18:18
  • @TheHeadRush There is no logical code except the one I have written in question.If you want me to paste the form code I will do that too .. but it doesn't help anyone – Cpt Kitkat May 13 '19 at 18:19
  • Ultimately, `this.contactForm` is undefined. Could be several reasons for that. 1) Is it actually in the template? 2) Are you sure you're importing the right `ContactformComponent`? – Adam Jenkins May 13 '19 at 18:50
  • Yes I am importing the Contact FormComponent – Cpt Kitkat May 13 '19 at 18:51
  • 1
    @ahmed - turn your component into a service. You're getting undefined because your component isn't initialized anywhere. To initialize it you would need to define it in the template somewhere. BUT please use a service like you suggest in the answer you are trying to copy. – Nanotron May 13 '19 at 19:10
  • share your component htmls as well – Naga Sai A May 13 '19 at 19:29

2 Answers2

0

Is the method public in the child component:

public saveContact() {
    //saveContact
 }

in the parent class...

export class A {
@ViewChild(ContactformComponent) contactForm: ContactformComponent;
AliWieckowicz
  • 549
  • 1
  • 4
  • 17
0

To resolve this issue, include child component in parent component.html

  1. Import ViewChild in your parent.component.ts

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

  2. Import Child Component in parent.component.ts and include child component in parent.component.html

parent.component.ts

import { Component, ViewChild } from "@angular/core"; import { ChildComponent } from "./child.component";

@Component({ selector: "app-root", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent { @ViewChild(ChildComponent) contactForm; saveContactForm() { console.log(this); setTimeout(() => this.contactForm.saveContact(), 0); } }

parent.component.html

<child></child>
<button (click)="saveContactForm()">Save</button>

On removing above mentioned child component from parent.component.html , it will throw below error in developer tools

sandbox.517cc37e.js:1 ERROR TypeError: Cannot read property 'saveContact' of undefined

working example - https://codesandbox.io/s/rlq4xj5q0n

Naga Sai A
  • 10,771
  • 1
  • 21
  • 40