0

I tried with the following child component class

@Component({
  selector: 'child',
  templateUrl: './child.component.html'
})
export class Child implements OnInit {
  @Output() send: EventEmitter<string>;
  public constructor(){}
  public ngOnInit() {
    send = new EventEmitter<string>();
  }
  public onEventXYZ() {
    this.send.emit('hello');
  }
}

and in the parent template i am referencing the above component as

<child (send)="handleSend($event)"></child>

it resulted in this error: Cannot read property 'subscribe' of undefined... on page load. When i later, on a friend's suggestion, moved the EventEmitter initialization from ngOnInit to the constructor, everything worked fine.

So, it too late to initialize component vars inside ngOnInit ?

oomer
  • 159
  • 3
  • 13

2 Answers2

1

I believe you're subscribing to the event received in the parent component. When you use the event binding signature ((send)="handleSend($event)") in the template, you don't have to explicitly subscribe to the event.

Try the following

parent.component.html

<child (send)="handleSend($event)"></child>

parent.component.ts

handleSend(event: any) {
  console.log(event);
  // no subscription is needed here
}

And as for the EventEmitter initialization, you could do it in the definition line. It doesn't affect the code.

child.component.ts

export class Child implements OnInit {
  @Output() send: EventEmitter<string> = new EventEmitter<string>();
  public constructor(){}
}
ruth
  • 29,535
  • 4
  • 30
  • 57
  • 1
    Michael D, i know it works with inline definition too, but i'm trying to find out, why is it too late to initialize the EventEmitter type var in ngOnInit ? – oomer Jul 15 '20 at 15:06
  • @oomer: That depends when you're calling `emit` on the `send` variable. The `ngOnChanges` hook is triggered before `ngOnInit`. So if you were to emit something inside `ngOnChanges`, you'll get the undefined error. There is no wrong in initializing it in the definition like I showed. – ruth Jul 15 '20 at 17:07
0

Angular subscribes sooner

Initializing in ngOnInit doesn't work because Angular subscribes to the EventEmitter before ngOnInit is called. And it cannot subscribe to it if it doesn't exist.

But initializing inline and initializing in the constructor works.

Some unrelated resources that elaborates my answer a little more:

Disclaim: I could not find any direct documentation to address this topic peculiarly

Kasir Barati
  • 606
  • 13
  • 24
  • i can't access the discord link you shared. – oomer Jun 26 '22 at 12:21
  • @oomer Do you have an discord link? If yes are you join in Angular discord server? if Yes, IDK what I should say except that I do have an [Angular project in GitHub](https://github.com/kasir-barati/my-angular-journey/blob/main/src/app/media/media.component.ts#L50) which I tried to elaborate it. I hope this will help you. – Kasir Barati Jun 27 '22 at 02:38
  • is this your observation about event emitter subscribing behavior (that it happens before ngOnInit is called) or did you read it somewhere in the docs ? – oomer Jun 27 '22 at 20:58
  • @oomer I am trying to add some references. But I could not complete it, yet. I hope newly added ref gave you a better understanding. BTW I will add a good ref if I find – Kasir Barati Jun 28 '22 at 05:54