Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Ari Misha
Ari Misha
19,323 Points

@Input and @Output in Angular

Hiya community! I just cant get my head wrapped around @Input and @Output decorators in Angular. Angular docs are making it really confusing for me to understand these concepts. I also tried reading blogs , couldnt find anything worth reading. So any help would be awesome! Thank you!

~ Ari

1 Answer

@Input

To define an input for a component, we use the @Input decorator.

For example, our <user-profile> component needs a user argument to render information about that user:

<user-profile [user]="currentUser"></user-profile>

So, we add an @Input binding to user:

import { Component, Input } from '@angular/core';

@Component({
  selector: 'user-profile',
  template: '<div>{{user.name}}</div>'
})
export class UserProfile {
  @Input() user;
  constructor() {}
}

@Output To create a custom event, we can use the new @Output decorator. Take the following component:

import { Component } from '@angular/core';

@Component({
  selector: 'user-profile',
  template: '<div>Hi, my name is {{user.name}}</div>'
})
export class UserProfile {
  constructor() {}
}

Let’s import Output and EventEmitter and create our new event

import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'user-profile',
  template: '<div>Hi, my name is {{user.name}}</div>'
})
export class UserProfile {
  @Output() userUpdated = new EventEmitter();

  constructor() {
    // Update user
    // ...
    this.userUpdated.emit(this.user);
  }
}

Now when we used this component in its parent component, we can bind the event that user-profile emits

  <user-profile (userUpdated)="handleUserUpdated($event)"></user-profile>
export class SettingsPage {
  constructor(){}

  handleUserUpdated(user) {
    // Handle the event
  }
}
Ari Misha
Ari Misha
19,323 Points

Alright! Thank you! I see , with @Output decorator, userUpdated emits an event, right? And it gets bubbled up to parent component. Why do we need $event?

Great answer. I like to think of @Input as values I want to pass into my child components and @Output as values to pass out of my component in a form of events.

$event will be the object you are passing from your child to whatever is listening to the event. So in the above example $event will hold the user object in the UserProfile class. $event will always depend on the type of event your are handling. So if you wanted to handle a click event like so

//app.component.html
<button (click)="onButtonClick($event)">Click Me</button>

//app.component.ts
private onButtonClick($event) {
     //here $event will be a mouseevent i belive. You can do stuff like
     $event.preventDefault();

}

I also agree the Angular docs are not that great yet, but here is one of their articles that shed light on all this sort of stuff

https://angular.io/guide/template-syntax