An Overview of Angular Component Interaction
Tags: angular, webdev, programming, javascript
Published: 2021-01-23 00:18:48

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

Angular is a popular front-end framework made by Google. Like other popular front-end frameworks, it uses a component-based architecture to structure apps.

In this article, we’ll look at some examples of Angular component interaction.

Pass Data From Parent to Child with Input Binding
=================================================

We can pass data from a parent component to a child component by using the `@Input` operator in the child component.

For example, we can write the following to do that:

`app.module.ts` :

```
import { BrowserModule } from '@angular/platform-browser';  
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';  
import { AppComponent } from './app.component';  
import { PersonComponent } from './person/person.component';

@NgModule({  
  declarations: [  
    AppComponent,  
    PersonComponent  
  ],  
  imports: [  
    BrowserModule,  
    AppRoutingModule  
  ],  
  providers: [],  
  bootstrap: [AppComponent]  
})  
export class AppModule { }
```

`app.component.ts` :

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

@Component({  
  selector: 'app-root',  
  templateUrl: './app.component.html',  
  styleUrls: ['./app.component.css']  
})  
export class AppComponent {  
  person = { name: 'Jane' }  
}
```

`app.component.html` :

```
<app-person [person]='person'></app-person>
```

`person.component.ts` :

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

@Component({  
  selector: 'app-person',  
  templateUrl: './person.component.html',  
  styleUrls: ['./person.component.css']  
})  
export class PersonComponent {  
  @Input() person;  
}
```

`person.component.html` :

```
<p>{{person.name}}</p>
```

In the code above, we have the `AppComponent` , which is the parent of `PersonComponent` .

In `AppComponent` , we have the `person` field, which is passed into the `person` property of `app-person` .

Then in the `PersonComponent` , we have:

```
@Input() person;
```

to get the `person` input value that’s passed in. Then we display the `name` property with:

```
<p>{{person.name}}</p>
```

in the template.

Then we should see ‘Jane’ on the screen.

Intercept Input Property Changes With a Setter
==============================================

We can add a setter to the `@Input` decorator to intercept the value that’s set and change it to something else.

For example, we can write the following code:

`app.component.ts` :

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

@Component({  
  selector: 'app-root',  
  templateUrl: './app.component.html',  
  styleUrls: ['./app.component.css']  
})  
export class AppComponent {  
  person = { name: 'Jane' }  
}
```

`app.component.html` :

```
<app-person [person]='person'></app-person>  
<app-person [person]='undefined'></app-person>
```

`person.component.ts` :

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

@Component({  
  selector: 'app-person',  
  templateUrl: './person.component.html',  
  styleUrls: ['./person.component.css']  
})  
export class PersonComponent {  
  private _person = {};  
  @Input()  
  set person(person) {  
    this._person = person || { name: 'Foo' };  
  } 

  get person() { return this._person; }  
}
```

`person.component.html` :

```
<p>{{person.name}}</p>
```

In the code above, we added getters and setters for the `person` property in the `PersonComponent` .

In the setter, we set `person` depending if `person` is defined or not. If it’s not then we set `this._person` to a default object. Otherwise, we set `this._person` to whatever the value is passed in from the parent.

In the getter, we get the `person` value that was set by return `this._person` .

The first line should display ‘Jane’ since we passed in `person` into `app-person` .

The second line should display ‘Foo’ since we pass `undefined` as the value of `person` .

Intercept Input Property Changes with ngOnChanges()
===================================================

We can use `ngOnChanges` to intercept the change and then set the value passed into the `@Input` field by changing it to what we want.

For example, we can write the following code:

`app.component.ts` :

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

@Component({  
  selector: 'app-root',  
  templateUrl: './app.component.html',  
  styleUrls: ['./app.component.css']  
})  
export class AppComponent {  
  person = { name: 'Jane' }  
}
```

`app.component.html` :

```
<app-person [person]='person'></app-person>  
<app-person [person]='undefined'></app-person>
```

`person.component.ts` :

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

@Component({  
  selector: 'app-person',  
  templateUrl: './person.component.html',  
  styleUrls: ['./person.component.css']  
})  
export class PersonComponent {  
  @Input() person; 

  ngOnChanges(change: { [propKey: string]: SimpleChange }) {  
    this.person = change.person.currentValue || { name: 'Foo' };  
  }  
}
```

`person.component.html` :

```
<p>{{person.name}}</p>
```

In the code above, we have the `ngOnChanges` hook in the `PersonComponent` .

It takes a `change` parameter that has the value of the change. In the hook, we check if `change.person.currentValue` is defined.

If it’s not, then we set `this.person` to `{ name: ‘Foo’ }` . Otherwise, we set `this.person` to `change.person.currentValue` .

Then we should see the same thing as in the first example.

Parent Listens for Child Event
==============================

We can call `emit` on an EventEmitter in the child component and then listen to the emitted event in the parent.

For instance, we can do that as follows:

`app.component.ts` :

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

@Component({  
  selector: 'app-root',  
  templateUrl: './app.component.html',  
  styleUrls: ['./app.component.css']  
})  
export class AppComponent {  
  person = {};  
}
```

`app.component.html` :

```
<app-person (emittedPerson)='person = $event'></app-person>  
<p>{{person.name}}</p>
```

`person.component.ts` :

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

@Component({  
  selector: 'app-person',  
  templateUrl: './person.component.html',  
  styleUrls: ['./person.component.css']  
})  
export class PersonComponent {  
  @Output() emittedPerson = new EventEmitter(); emitPerson() {  
    this.emittedPerson.emit({ name: 'Jane' });  
  }  
}
```

`person.component.html` :

```
<button (click)='emitPerson()'>Get Person</button>
```

In the code above, we have the `emitPerson` method in the `PersonComponent` , which calls `emit` on the `emittedPerson` emitter, where we pass in the payload to send to the parent.

Then in `app.component.html` , we have:

```
<app-person (emittedPerson)='person = $event'></app-person>
```

to listen to the `emittedPerson` event from `app-person` and then set the `person` field to the `$event` variable passed in from the child by calling `emit` .

Then we have:

```
<p>{{person.name}}</p>
```

to display the `name` property value from the emitted object.

Therefore, when we click the Get Person button, we should see ‘Jane’ displayed.

Conclusion
==========

We can pass data from a parent to a child by using the `@Input` decorator in the child.

To pass data from a child to a parent, we can emit an event from the child. Then the parent can listen to it and then run code to do something with it.

`$event` has the object that’s passed in with the `emit` call.