Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 why use @Output over @Input for callbacks

I am learning Angular2, after working with Angular1 for a couple of years. I'm creating a credit card form component, with the main goal to learn a couple of key concepts in Angular2. The component should handle all formatting, and return a Stripe token through a callback. I realised that I can handle callbacks in two ways.

Using an @Output parameter

In my component I define a output variable and use it like in this example:

export class CreditCardForm{
    ....
    @Output () callback = new EventEmitter();
    ....

    doCallback(){
        this.callback.emit({data: 123});
    }
}

// Parent view
<credit-card-form (callback)="creditCardCallback($event)"></credit-card-form>

Using an @Input variable

However, I could just pass the callback method (creditCardCallback, used in the parent template) to an input variable, like this:

export class CreditCardForm{
    ....
    @Input () callback;
    ....

    doCallback(){
        this.callback({data: 123});
    }
}

// Parent view
<credit-card-form [callback]="creditCardCallback"></credit-card-form>

The question

Why would I want to use @Output over @Input? What do I achieve by using @Output variables instead? As far as I can see, this just adds an overhead by having to utilise the EventEmitter class.

like image 931
Anton Gildebrand Avatar asked Oct 16 '16 09:10

Anton Gildebrand


People also ask

What is the difference between @input and @output in angular?

@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.

What is the use of @output decorator?

Use the @Output() decorator in the child component or directive to allow data to flow from the child out to the parent.

What is @input and @output in angular 2?

The above pattern — passing data in through an “input” property and sending data out through an “output” event — is the primary way to share data between Angular 2 components.


2 Answers

There are always more than one way to skin the cat. However, in my opinion, using @Output has these benefits:

  • Code readability: It's easier to know the flow of data if using the recommended style.

  • De-coupling: For example, for normal @Output event, in your ParentComponent, you can have more flexibility of handling the dispatched event:

  • Last but not least - it enables banana in the box syntax: Say in your ChildComponent you have:

@Input() creditCardValue: string; @Output() creditCardValueChange: EventEmitter<string>;

Then you can have two-way binding in your ParentComponent easily:

<credit-card-form [(creditCardValue)]="creditCardVal"></credit-card-form>
like image 68
Harry Ninh Avatar answered Nov 16 '22 03:11

Harry Ninh


Imho, @Output is a HUGE design flaw, as you can't react to the result, or handling of it. The number one example of this flaw is the click of a button. When clicked, the button should be disabled 99% of the cases when the action is taking place. Once the action is done, the button should be enabled again. This is something you want to handle in the element itself, not in the parent. With @Output, you can't do this. Using an action function as @Input, you can do this! And if your action function returns an Observable or Promise, you can easily wait for it. Creating a custom directive that handles this disabling is easy, and thus you can use [click] everywhere and it will behave that way.

EDIT: I don't say @Output doesn't have it's uses, but not for actions you need to wait on etc.... Naming your @Inputs good, also clarifies the flow, like onDelete etc...

like image 22
Dieter Geerts Avatar answered Nov 16 '22 03:11

Dieter Geerts