2

For the example at url:

http://ngcourse.rangle.io/handout/components/app_structure/two_way_data_binding.html

I am unable to understand how the following two lines function with respect to @Output

//in app.component.ts
    (countChange)="number2=$event"
    (countChange)="onCountChanged($event)


//counter.component.ts
@Output() countChange: EventEmitter<number> = new EventEmitter<number>();

can someone help connect the dots here.

3 Answers 3

1

In simple terms,

To trigger custom events, EventEmitter is used (generally from childcmp to parentcmp). @Output is a way to declare custom event name (type of EventEmitter).

In your case it is (from counter.component.ts),

@Output() countChange: EventEmitter<number> = new EventEmitter<number>();

says countChange is a custom event (type of EventEmitter). EventEmitter has methods like emit(), next() which can emit values. So here it says countChange can emit number value. eg.

count=5;
buttonClick(){
    this.countChange.emit(this.count); // will emit 5 value 
}

Note whenever EventEmitter (here countChange) emits any (number) value, custom event(generally used in parentcmp) will be triggered by its own.

In your case it is (from app.component.ts),

(countChange)="number2=$event"  //number2=5; //countChange is a custom event

automatically this.count's 5 value will be received through $event and so it will be assigned to number2. which is also applicable for below code.

(countChange)="onCountChanged($event)  //countChange is a custom event

somewhere written in component.

onCountChanged(value)
 {
      console.log(value); // =5;
 }    
Sign up to request clarification or add additional context in comments.

1 Comment

I think anyone who's walked through a tutorial, understands what the effect of using @Output is within the context of using EventEmitter<T>. The question that we're all asking, if I may, is: Does @Output create new & custom event-types? Or does it depend on what the context is? What if I assign @Output notAnEvent = [ 1, 2, 3 ]? How in the world does Angular know what the event's name/type is, unless we assume to have some TypeScript magic? What makes @Output and output? And finally, what's the difference b/w this approach & using @Input to pass in a callback (as in React)?
1
this.countChange.emit('foo');

in counter.component.ts dispatches an event

(a bit similar to a click or other DOM event, but only handled in Angular internally)

(countChange)="onCountChanged($event)

registers a listener for this countChange event.
It might be a bit confusing because Angular uses the same binding syntax for @Output() as for DOM events.

When this.countChange.emit('foo'); is executed the registered event handler is called and 'foo' is passed (for the $event argument).

Comments

1

I actually think Angular's own examples on how @Input and @Output work are pretty poor.

Here is a simple StackBlitz example, which shows how it's done: https://angular-ivy-yqycev.stackblitz.io

It looks like this:

enter image description here

When you type in characters in the "transmitter" textbox, it'll send your string as an @Output... and the "receiver" will receive it via as an @Input, and show it in it's own textbox.

The key thing is that the "Transmitter" component will use an @Output...

transmitter.component.html:

<div>
  <h3>Transmitter</h3>
  <input type="text" [(ngModel)]="value" (ngModelChange)="onChange($event)" />
</div>

transmitter.component.ts:

  @Output() emitter = new EventEmitter<string>();

  onChange(event:any) {
    this.emitter.emit(this.value);
  }

And the "Receiver" component will use an @Input()...

receiver.component.html:

<div>
  <h3>Receiver</h3>
  <input type="text" [(ngModel)]="inputValue" />
</div>

receiver.component.ts:

  @Input() inputValue = "";

And, you can tie them together using this:

app.component.html:

  <app-transmitter (emitter)="onEmitter($event)"></app-transmitter>
  <app-receiver [inputValue]="currentValue"></app-receiver>

app.component.ts:

export class AppComponent  {

  currentValue = '';

  onEmitter(event:any) {
      console.log('Received: ' + event);
      this.currentValue = event;
  }
}

Hope this helps !

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.