Reputation: 538
I'm passing a function as parameter from parent to child component. When click event is occurred, function of parent component trigger, but all the property of parent component is undefined. For example,
Parent Component
export class AppComponent implements OnInit {
constructor( private notificationService: NotificationService ) {}
unreadNotification(): Observable<any> {
// here this.notificationService is undefined
console.log( this.notificationService );
}
}
Parent html
<notification-menu [unread]= "unreadNotification"></notification-menu>
child Component
export class NotificationMenuComponent implements OnInit {
@Input() updateUnread: Function;
}
child html
<button type="button" class="icon-button" (click)="updateUnread()">
</button>
Now when I click on notification button, unreadNotification
is triggered, but value of this.notificationService
in console.log
is undefined
.
How can I solve this?
Upvotes: 1
Views: 475
Reputation: 2025
You can use arrow
function so that you can use parent component's information. You can try as like as given below.
updateUnreadNotification = () => {
// by using arrow function you can get notificationService information
console.log( this.notificationService );
}
Hope your problem will be solve by this.
Upvotes: 1
Reputation: 2454
The answer from @nimeresam is good advice - using an @Output
is an idomatic way to achieve this.
It's worth noting though, that the reason that your original solution doesn't work is due to the way that javascript handles the this
context.
Writing (click)="updateUnread()"
is equivalent to saying this.updateUnread()
with this being NotificationMenuComponent
- as notificationService does not exist on NotificationMenuComponent you get the undefined error.
To have the context of the parent component used, you would need to bind the context to the updateUnread
function before passing it into the child component.
This can be achieved either by converting the function to be an arrow functionn, or using Function.bind
See:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
It's normally a good idea to enable the typescript option for --noImplicitThis
to help catch these errors (though unsure if it will detect it in this case)
Upvotes: 2
Reputation: 4199
You should use @Input()
to pass values from parent to child and @Output()
to pass values from child to parent.
Child HTML:
<button type="button" class="icon-button" (click)="update()">
</button>
Child Component:
export class NotificationMenuComponent implements OnInit {
@Output() updateUnread = new EventEmitter<string>();
update() {
this.updateUnread.emit("I am working man!");
}
}
Parent HTML:
<notification-menu (updateUnread)= "unreadNotification($event)"></notification-menu>
Parent Component:
export class AppComponent implements OnInit {
constructor( private notificationService: NotificationService ) {}
unreadNotification(dataFromChild: string) {
console.log(dataFromChild);
}
}
Upvotes: 2