1

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?

0

3 Answers 3

2

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);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

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)

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.