I've a component that takes function as input. I've passed this function from parent.
Though the function is called, the function is not able to access the dependencies of the instance on which this function is declared.
Here is the component
@Component({
selector: 'custom-element',
template: `
{{val}}
`
})
export class CustomElement {
@Input() valFn: () => string;
get val(): string {
return this.valFn();
}
}
Here is how the component is used
@Injectable()
export class CustomService {
getVal(): string {
return 'Hello world';
}
}
@Component({
selector: 'my-app',
template: `
<custom-element [valFn]="customVal"></custom-element>
`,
})
export class App {
constructor(private service: CustomService) {
}
customVal(): string {
return this.service.getVal();
}
}
When I run this app, I get an error in the console saying Cannot read property 'getVal' of undefined
Here is a plunker for the issue.
https://plnkr.co/edit/oQ229rXqOU9Zu1wQx18b?p=preview
In your child component, add an @Input variable to bind the parent component's passed function: @Input() callbackFunction: (args: any) => void; Make sure that the signature definition of your @Input() function matches the myCallbackFunction that you defined in the parent component.
@Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component. Conversely, @Output() lets the child send data to a parent component.
To let Angular know that a property in a child component or directive can receive its value from its parent component we must use the @Input() decorator in the said child. The @Input() decorator allows data to be input into the child component from a parent component.
You need to .bind(this)
if you pass methods around:
<custom-element [valFn]="customVal.bind(this)"></custom-element>
or
export class App {
constructor(private service: CustomService) {
}
customVal(): string {
return this.service.getVal();
}
customValFn = this.customVal.bind(this);
}
with
<custom-element [valFn]="customValFn"></custom-element>
You can pass a get/set property instead of a function in a similar way like that:
Somewhere in your view:
<input type="text" [(ngModel)]="yourprop">
In your component file:
@Component({
selector: 'myapp',
templateUrl: './myapp.component.html',
styleUrls: ['./myapp.component.scss']
})
export class App {
constructor() { }
yourprop: any;
get yourprop(): any {
return this.scheduleEndDate;
};
//set accessor including call the onchange callback
set yourprop(v: any) {
// TODO do something else
// You can do whatever you want just like you have passed a function
if (v !== this.scheduleEndDate) {
this.scheduleEndDate = v;
}
}
}
more info @ https://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With