Passing data between nested components with Angular
Tags: angular, webdev, javascript, beginners
Published: 2017-12-20 09:55:51

---
title: "Passing data between nested components with Angular"
published: true
tags: Angular,WebDev,JavaScript,Beginners
canonical_url: 
---

One of the biggest changes from AngularJS to Angular (2+) is the step away from two-way data binding. The problem with two-way data binding is the potential for unexpected cascading effects and can be hard to reason about the bigger the project is. With the change to one-way data binding in Angular, data is passed down through components and if a changed is required as a result of some action, it is emitted back up to the top where the change is actually made because Angular applications are made up of a hierarchy of components.

This is achieved through a combination of defining the input and output properties of the child-element in the parent component html and the `@Input` and `@Output` of the child component.

> Input and Output as an API for your component

In other words, a component can receive data from its parent as long as the receiving component has been specifically defined (or exposed) ways to receive that data, just like how an API functions. Similarly, components can send data to their parents by triggering an event the parent listens for.

Here’s a graphic of how it works between Parent and Child:  
 ![Parent-Child Component Data Comm](https://i0.wp.com/www.chiangs.ninja/blog/wp-content/uploads/2017/11/Screen-Shot-2017-11-09-at-12.50.55-copy.png?resize=932%2C683&ssl=1)

Just remember that in the ParentComponent.html as you define the ChildComponent, the child properties are on the left, and the parent are on the right, sort of like when you declare a variable and assign it a value where the variable is on the left side of the `=` and the value is on the right.

![ParentComponent.html input/output](https://i0.wp.com/www.chiangs.ninja/blog/wp-content/uploads/2017/11/Screen-Shot-2017-11-09-at-12.51.03-copy.png?resize=896%2C551&ssl=1)

It is important to note that doing this for more than 1 or 2 layers of nested components or across to same level components can get complicated and pretty confusing. A better way to centralize this data is through the use of services, which I’ll write about in the next article.

Here, I’m going to create a ParentComponent and ChildComponent, instantiate a new object of a Stephen class(model) in the ParentComponent and then pass the ChildComponent a specific array of properties of the Stephen object. After that, I’ll define an output where when one of the properties is clicked, the ParentComponent acknowledges the event and changes the way I’m addressed: Mr. Stephen | Chiang | Stephen E. Chiang.

### Create a new Angular project using the CLI, if you don’t have one set up yet: `$ ng new parent-child`

- Create a parent and child component that is nested in the parent.

-Create a simple class, in this case, I’m just creating a model of myself a `stephen.model.ts`

```
$ ng g c parent
$ ng g c parent/child
$ ng g class stephen
```

In the model, I’ll add the following attributes:

```
export class Stephen {
    firstName: string = 'Stephen';
    lastName: string = 'Chiang';
    fullName: string = 'Stephen E. Chiang';
}
```

In the `app.component.html` file, we’re going to erase the default filler and add the ParentComponent element: `<app-parent></app-parent>`

### In the `parent.component.ts` file, we’re going to make an instance of the object:

- Import the Stephen class.
- Declare the object and instantiate a new instance in the constructor.
- Declare the first name property as the default to display upon construction of the ParentComponent to show that you’ve properly instantiated the object.
- Define the ChildComponent input name `[stephen]` to accept the ParentComponent’s `stephen: Stephen` object.
- Define the ParentComponent output named `(onNameSelected)` and assign that to an operation in the ParentComponent that updates the `selectedName` by calling the ParentComponent’s `updateName` function.
- Define the `updateName` function to set the new name based on the string that will be emitted by the ChildComponent via the Output.
- Because of how simple this example is, there’s no need to separate the `parent.component.html` and `parent.component.ts` code so we’re going to do it inline.
- Also of note, if updates to the `selectedName` were to occur from within the ParentComponent, one would need to subscribe to the property to update changes, but in this case change notice will be sent from outside (ChildComponent), so the ParentComponent is already listening for changes.

```
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { Stephen } from '../stephen.model';

@Component({
    selector: 'app-parent',
    template: `
    
        Hello, Mr. (or Ms.): {{ selectedName }}

`,
styleUrls: ['./parent.component.css'],
    encapsulation: ViewEncapsulation.None
})

export class ParentComponent implements OnInit {
    stephen: Stephen;
    selectedName: string;

    constructor() {
        this.stephen = new Stephen();
        this.selectedName = this.stephen.firstName;
    }

    ngOnInit() {
    }

    updateName(selectedName: string): void {
    console.log('in parent');
    this.selectedName = selectedName;
    }

}
```

&nbsp;

If you were to run `$ ng serve` right now, all you’d see is:  
 ![child works!](https://i0.wp.com/www.chiangs.ninja/blog/wp-content/uploads/2017/11/Screen-Shot-2017-11-09-at-17.00.22.png?resize=960%2C302&ssl=1)

### In the ChildComponent:

- Import Input, Output, and EventEmitter as well as Stephen or whatever you named your model class.
- Make a simple unordered list and for each list item, string interpolate each attribute.
- Each list item has a `(click)` event that calls the `clicked` function and passes the attribute.
- Declare the `@Input() named as`stephen` to match how its defined in its element of the ParentComponent html.
- Declare the `@Output() named as`onNameSelected` to match and set it as an EventEmitter type that emits a string.
- Instantiate a new `EventEmitter` in the constructor and set it to the EventEmitter declared as the @Output().
- Define the `clicked` function that takes a string and calls the output EventEmitter to emit the string back to the parent.
- There are more efficient ways to display the information, for example, making the name attributes a string[] and then use `*ngFor` to iterate and create a `

` element for each item in the array, which would reduce repeated code, but for this quick and simple example, it works just fine.  
– Here you see we did not instantiate a new Stephen object, and yet we were able to access the attributes. You could have also passed in specific attributes of the object instead of the entire thing if you wanted.

&nbsp;

```
import { Component, OnInit, ViewEncapsulation, Input, Output, EventEmitter } from '@angular/core';
import { Stephen } from '../../stephen.model';

@Component({
    selector: 'app-child',
    template: `

        {{ stephen.firstName }}
        {{ stephen.lastName }}
        {{ stephen.fullName }}
        `,
    styleUrls: ['./child.component.css'],
    encapsulation: ViewEncapsulation.None
})

export class ChildComponent implements OnInit {
    @Input() stephen: Stephen;
    @Output() onNameSelected: EventEmitter;
    
    constructor() {
        this.onNameSelected = new EventEmitter();
    }
    
    ngOnInit() {
    }
    
    clicked(name: string): void {
        this.onNameSelected.emit(name);
    }
}
```

At this point, your app should work, when you click on one of the names, it will update the parent:  
 ![list to update parent](https://i0.wp.com/www.chiangs.ninja/blog/wp-content/uploads/2017/11/Screen-Shot-2017-11-09-at-17.20.42.png?resize=874%2C376&ssl=1)

Here’s a chart that shows both Parent and Child side by side to further help illustrate how it all ties together with details removed.  
The ChildComponent emits back up to the ParentComponent and lets the parent decide what to do with the event. This helps keep logic in fewer and more logical places than complex logic in every single component in the entire app.  
 ![parent-child](https://i0.wp.com/www.chiangs.ninja/blog/wp-content/uploads/2017/11/parent-child.png?resize=981%2C753&ssl=1)

Using this method to pass data cross-component or in heavily nested components (more than 3 layers) can get confusing. If you find yourself needing to pass a specific piece of data around a lot, it might be time to think about centralizing it and using a **service** , which I will discuss using the same example in the next article, which will be in the next few days because we’re expecting a little baby girl any day now and I better get this next article out now, otherwise it could be weeks or months!

Please don’t hesitate to send your questions, comments, criticisms and follow me here or any of my social media accounts.

Thanks!

Stephen