Author avatar

Gaurav Singhal

Passing Data to a Nested Component with @Input

Gaurav Singhal

  • Nov 7, 2019
  • 5 Min read
  • 6 Views
  • Nov 7, 2019
  • 5 Min read
  • 6 Views
Languages Frameworks and Tools
Angular

Introduction

In this guide, we are going to learn about @Input(). One of the most useful decorators in Angular, it sends data over to the component and helps you get required data from a parent component. We’ll discuss more about this decorator in the following sections.

About @Input()

This decorator marks a field as an input and supplies the configuration metadata. It is used to tell the component this field data will be coming from parent's data. It receives the data before calling the ngOnInit() method, so you can use it in ngOnInit() method.

ngOnInit() is one of the lifecycle hooks in Angular, called after the constructor() and ngOnChanges() method. You can learn more about angular lifecycle hooks here.

Need for @Input()

@Input() is used to interact between components. Angular has different types of interactions between components, but @Input() is used to make the interaction between parent-child types of component. There are various ways we can interact with one component to another components. Some methods you can use to communicate the component include:

  • Using services
  • @viewChild()

@Input() is mainly used in the hierarchy level between parent and child is small. If there is a larger hierarchy, I suggest you use a service.

How to use @Input()

Now we'll dive in the coding part to give you a better idea of how to use @Input().

First, we're going to make two components. Open your cmd, go to your project folder path, and type the command below.

1
2
ng g c components/parent --skipTests=true
ng g c components/child --skipTests=true
console

We have successfully created the components. Now it's time to use the @Input() decorator.

app.component.html

1
<app-parent></app-parent>
typescript

In app.component.html, we call the parent component.

parent.component.html

1
<app-child [parentData]="data" [data]="data"></app-child>
html

In the parent component, we call the child component. But you can see some additional attributes in the <app-child> component. This is because we're going to use @Input() in the <app-child> component.

The @Input() decorator is going to tell the component that this field comes from the parent component. You may notice we wrote parentData and data, which is an attribute for app-child as it is under the pair of square brackets('[]'). This is because we have to set the dynamic data to the parentData and data attribute, which will come from the class file of the component. So we're passing the data which is instantiated and initialized in the parent component. You can see this in the following code:

parent.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { Component, OnInit } from "@angular/core";

@Component({
  selector: "app-parent",
  templateUrl: "./parent.component.html",
  styleUrls: ["./parent.component.scss"]
})
export class ParentComponent implements OnInit {
  data: string;
  constructor() {}

  ngOnInit() {
    this.data = "Hii from parent";
  }
}
typescript

As you can see in the ngInInit() method, we set the value of the data, which will be fetched in the HTML file, and set the parentData and data.

We are now done with the parent side code. No more code is required on the parent side to send the data from parent to child. Now let's see the code on the child side.

child.component.html

1
2
{{parentData}}<br />
{{modifiedName}}
html

In child.component.html, we bind the data from child.component.ts to print in the child component.

child.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Component, OnInit, Input } from "@angular/core";

@Component({
  selector: "app-child",
  templateUrl: "./child.component.html",
  styleUrls: ["./child.component.scss"]
})
export class ChildComponent implements OnInit {
  @Input() parentData;
  @Input("data") modifiedName;

  constructor() {}

  ngOnInit() {
    console.log("This is the parent data", this.parentData);
    console.log("This is the parent data", this.modifiedName);
  }
}
typescript

This seems like magic, and we need to pay more attention to this part of the code.

We use @Input() decorator to get the data from parent. You may wonder why we’ve written two different syntaxes for the @Input()—that is, @Input() and @Input("data"). This is because if we have to use the same name in the child class, i.e., same as an attribute name, we have to write it in the app-child tag in the parent.component.html so that we don't have to pass anything in the @Input(). It will by default search for the name that matches the variable name of the child component.

But if we have to use a different name for an attribute and a different name for a variable, then we need to pass the attribute name in the @Input(), which is data in our case.

Our output would look something like this:

Remember, I said the @Input() field gets the data before the ngOnInit() method is called. Therefore, I'm printing the data in the console, which will look like the snippet below.

Summary

Interaction between components and nested components is a necessary feature in midsize to large web applications. @Input() is one of the most useful decorators in Angular, and interviewers often ask about it. You’re likely to hear this question in the future, and after reading this guide, you should be able to answer related questions.

0