Reputation: 2157
We are trying to pass the array data from the Parent component to the Child and it is throwing TypeError: Cannot read property 'setData' of undefined
> Below is what we are trying
Parent Component
export class RFComponent implements DoCheck {
finalResult: SModel[];
@ViewChild(TSFComponent, {static: false})
private childVar: TSFComponent;
........
click() {
this.elem = this.getResult(this.prj);
this.childVar.setData(this.finalResult);
}
Child Component
export class TSFComponent implements DoCheck {
@Input() setData(e: SModel[]) {
this.tjlData = e;
}
I am not sure why we get Cannot read property
error we call setData() from the parent
Upvotes: 0
Views: 130
Reputation: 1064
You're using @ViewChild wrong. You don't need to use the setData() function to essentially 'set' the data. If you use the @Input() decorator in the Child component, you can set the and declare the variable there with the data passed down from the Parent Component.
You can do it like this:
Parent Component HTML:
<child-component [parentData]="data"></child-component>
Child Component .ts
@Input data: any;
Then, if you want to set a variable or object equal to the Child Component variable/object, then reference the child component variable in the parent component and assign the value. See below:
Child Component giving the data object a new value
someCode() {
data = {
someData: "Hi there",
someMoreData: "Hello there again"
}
Parent component referencing and assining a new object
parentData: any;
assignData {
this.childComponent.data = parentData;
}
Upvotes: 0
Reputation: 190
As far as I see, you do not need the Input() decorator, and it should work if you remove it. Precondition is, as already mentioned, that the TSFComponent is actually used inside the template of RFComponent.
Upvotes: 0
Reputation: 1861
You don't need to define setData() on the child as an Input(). You are creating a reference to the child component when you use viewchild and therefore you can access the methods on it. You are not passing the method setData from parent to child.
export class TSFComponent implements DoCheck {
setData(e: SModel[]) {
this.tjlData = e;
}
You also need to give reference to the dom element in view child.
<child #TSFComponent></child>
@ViewChild('TSFComponent', {static: false}) childVar: TSFComponent;
Upvotes: 0
Reputation: 5770
Please recheck your RFComponent
. There you will see that this.finalResult
is not defined anywhere. You need to define it as member variable, like for example
private finalResult: string = 'something'
then you will be able to pass it to the other component.
But also, this is not the best practice to do. As far as I see here you did not define your components correctly. Even though you can have pure classes in Angular, usually components have a decorator over the class declaration, where you define your selector, templateUrl and styles, e.g.
@Component({
selector: 'some-selector',
templateUrl: 'my-template.component.html',
styleUrls: ['my-style.component.scss']
})
There, in the template you can then reference the other class and pass data over @Input()
, @Output()
parameters.
Upvotes: 1