Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Component Communication in Angular, Day 1

DZone's Guide to

Component Communication in Angular, Day 1

In this article, we explore all things components in Angular, from creating them to passing data between them. Let's get started!

· Web Dev Zone ·
Free Resource

Learn how error monitoring with Sentry closes the gap between the product team and your customers. With Sentry, you can focus on what you do best: building and scaling software that makes your users’ lives better.

Components are the basic building blocks of Angular applications. In a simpler manner, we can say components are UI/ View elements along with the mechanism to show and operate on data.

The Angular Team defines a component as the Patch of the screen that we call a View which declares the reusable building blocks for an application. So, a component is anything which is visible on the screen, which can be reused again and again.

Creating Components

As we are using the Angular CLI, we can create the component in one command. If you don’t know how to set up the project using CLI, please visit this link:

http://www.c-sharpcorner.com/article/angular-basics-and-quikstart-with-cli/

When you are done with the project setup, you are ready to add our new component by using the following command:                 

Image title

All right, in my case, I will run the command ng generate component myfirstcomponent (This is the name of my component, you can choose your own). This will generate the following folder structure in your application:      

Image titleWhen we create the component, Angular CLI creates the folder with the name of the component and it adds the files myfirstcomponent.component.ts, myfirstcomponent.component.spec.ts, myfirstcomponent.component.html, and myfirstcomponent.component.css files in the folder myfirstcomponent.

One more change that we can see is in the AppModule.ts file.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { MyfirstcomponentComponent } from./myfirstcomponent/myfirstcomponent.component';

@NgModule({
  declarations: [
    AppComponent,
    MyfirstcomponentComponent
  ],
  imports: [
    BrowserModule
  ],
  exports:[AppComponent],
  providers: [],
  bootstrap: [AppComponent]
})

export class AppModule { }

As we have one module so far in the application, whenever we add the component in the CLI it adds that component directly in the app module, which is the root module of the application. It imports the component in the root module and adds it into the declaration section which contains all the components present in the module.

Exploring Our First Component

When we look at our first component it adds the snippet like below.

Its main section is an export of the component from the Angular core which is needed to mark the class as a component.

Next thing which needs to see are:

  1. selector: a property which tells Angular to create an insert of this component whenever it sees the element in the template.

  2. templateurl: it is the URL of the HTML page which tells Angular what needs to be shown in the UI.

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

@Component({
  selector: 'app-myfirstcomponent',
  templateUrl: './myfirstcomponent.component.html',
  styleUrls: ['./myfirstcomponent.component.css']
})

export class MyfirstcomponentComponent implements OnInit {
name:string="John Doe";
constructor() { }
  ngOnInit() {
  }
}

So how does it work? First, Angular sees the selector for the component and it searches for the selector in the HTML and replaces the template so that the templateUrl is rendered in that section. In our case, the selector is app-myfirstcomponent and the template is the myfirstcomponent.component.html file, which will be rendered in the browser.

How to Use This Component

Ok, we know how to add and some basic stuff with components, so now let’s see how to use them in the View. To use this component, we must keep in mind the selector property of the component, which, in our case, is app-component. To use this, just add this line in the app.component.html file: <app-myfirstcomponent></app-myfirstcomponent>. So the code snippet for app.component.html will be like what I've got below:

<div >
<h1>
{{title}}
</h1>
<h1>
<app-myfirstcomponent></app-myfirstcomponent>
</h1>
</div>

We have seen that the selector will load the HTML in the which the second property of the component decorator (templateUrl) is specified. When we see the template URL, it is like I've got below:

<p>
hello {{name}}  your first component works!
</p>

So, to sum up, we can say the selector is the name of the component which will be used by Angular to call the components inside the HTML file.

Passing Data Between Components

Ok, we have seen how to we create and consume the same component in an application. Now, let’s see how we can share data between the components.

There are basically four ways to pass data between components; let's look at them one-by-one.

Before that, let’s see what we mean by parent and child components. The parent component is the component which acts as the container for other components, and a sibling is a component which is not in the container but which is not related to the other components.

Image title

The following points are the ways we can pass the data between parent and child components.

1. Parent Component to Child Component

There will be always a need to send data between the parent component and the child component. Let’s see step by step how we can achieve this.

@Input:

This decorator is used to obtain data from the component. To achieve this, I have made changes to the component. Let’s add two components, namely a master and a child component, in the application by using Angular CLI's ng generate command.

When the components are added look at the code snippet for the child component (child.component.ts)

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

@Component ({
  selector: 'child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})

export class ChildComponent implements OnInit

{
  @Input("bindingmessaage") message:string
  constructor() { }
  ngOnInit()
  {

  }
}

Here we have used the @Input decorator for making the message an input; let’s look at the syntax of the @Input decorator in detail. Here, bindingmessage, (which is included in the code above like so: @Input("bindingmessage")) is used as the alias of the message property which can be used in other components.

Ok, we have made the message property of the ChildComponent that accepts values from the parent component; so how do we assign the values to this variable? For that purpose, we must examine the parent component (remember this is a parent-child interaction). We must make the provision in the parent component to set the values of this variable for that change.

To do so, we must add the child component to the master component, but how do we do that?  We have selectors for our use here. Let's look at the following HTML (Master.component.html) snippets:

Master.component.html

<child bindingmessaage="Message from the Parent Without Binding">

</child> 

app.component.html

<div id="parent-to-child">
    <div>
<master></master>           
    </div>
</div>

This code simply adds the master component in the app component, which is our root component, and the master component, in return, adds the child component in its template.

When we run the application, we can see the following output: 

This is child component

This is Message from parent:: Message from the Parent Without Binding

Now, to pass the value from the parent component to the child component we have to make the following changes.

Update the Master component (Master.component.ts) to the following snippet:

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

@Component({
  selector: 'master',
  templateUrl: './master.component.html',
  styleUrls: ['./master.component.css']
})

export class MasterComponent implements OnInit {
  sendgreetingtochild:string="Data from Parent to child using input decorator";
  constructor() { }
  ngOnInit() {
  }

}

And in the child template selector, which is present in the master.component.html file, make the following changes:

<p>
<child [bindingmessaage]="sendgreetingtochild"></child> 
</p>

What we are doing here is we are assigning the value of the property  sendgreetingtochild to the bindingmessage input of the child component.

When we save the file, we get the following output:

This is child component
This is Message from parent:: Data from Parent to child using input decorator

We can see the changed output which is the same as where we have assigned the value of the variable in the master.component.ts.

To sum up, we can say that in order to pass the value from parent to child the following steps must be taken:

  1. Use @input for the properties to which we want to assign a value. For example: @Input("bindingmessaage") message:string  

  2. Use the property in the selector of the child componen. For example: <child [bindingmessaage]="sendgreetingtochild"></child> 

2. Passing Data From Child to Parent (Using @Output) and Event Emitters

We have seen how we can pass data from the parent to the child component, now let’s look at how to pass data from the child to parent component using @output and Event Emitters.

In this, the child component emits the data to the parent component by using the @output decorator and event emitter. This change can occur on a button click or any data change in between.

To achieve this, we can perform the following steps:

  1. The parent should have the provision to receive this message which will be assigned and used.

  2. The child should have the variable decorated with @output and a function which will emit this event. And the message which we want to send to the parent component.

Let us add two components as follows using the ng generate command:

  • ChildwithoutputandemiterComponent.component.ts will be our child component.
  • MasterwithoutputandeventemiterComponent.component.ts will be our master component.
  • In order to see how we can use the  @output decorator and event emitters, lets modify the child component with the following snippet.

    import {
        Component,
        OnInit,
        Output,
        EventEmitter
    } from '@angular/core';
    
    @Component({
        selector: 'app-childwithoutputandemiter',
        templateUrl: './childwithoutputandemiter.component.html',
        styleUrls: ['./childwithoutputandemiter.component.css']
    })
    
    export class ChildwithoutputandemiterComponent implements OnInit {
        message: string = "Hello from child"
        @Output("messagefromchid") EventEmitter < string > ();
        EmitValue(): void {
            this.emitmessage.emit(this.Message)
        }
    
        constructor() {}
        ngOnInit() {}
    }

    Before understanding the code, lets look at some basic things we have in this snippet, specifically @output and EventEmitter .

    @Output

    The attribute which is used when we want to send the data outside of the component.

    This attribute is always combined with the event emitter which can be accessed outside of the component by using the event that is passed.

    EventEmitters

    Event emitters are used in Angular to emit events in the components.

    When we see the description of the above code we can see that we have used the @Output attribute and we have set it to the new EventEmitter, and we also have the method EmitValue which emits the value of the message property to the master component.

    Next, let's look at how the master component handles these values:

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-masterwithoutputandeventemiter',
      templateUrl: './masterwithoutputandeventemiter.component.html',
      styleUrls: ['./masterwithoutputandeventemiter.component.css']
    })
    
    export class MasterwithoutputandeventemiterComponent implements OnInit {
    
    GreetingsFromChild:string ="Initial message at the master.";
     receivemessage($event):string
      {
    this.GreetingsFromChild=$event;
    return this.GreetingsFromChild;
      }
    
    constructor() { }
      ngOnInit() {
      }}

    What we have done in this code is we have created the function receivemessage which receives the value from the event emitter. 

    To see the output, we have to make some changes with the child and parent templates. 

    This is the child template (HTML file) which has one input and we can see that the EmitValue() from the child component will be called whenever a button click happens. Another change that we need to make is to change the master component like below:

    <p>
     <b> Master component :: </b>
      <br> 
      <b> {{GreetingsFromChild}}</b>
    <br>
    <app-childwithoutputandemiter (messagefromchid)($event)></app-childwithoutputandemiter>
    </p>

    When we look at the code, we can see that we have added the child component inside the master component in order to receive the output. What we have done is we have assigned the  receivemessage($event) to  messagefromchild.

    This was all about the passing of the data from the parent to the child and child to parent. We will other techniques, like @viewchild using services, in the next article.            

    What’s the best way to boost the efficiency of your product team and ship with confidence? Check out this ebook to learn how Sentry's real-time error monitoring helps developers stay in their workflow to fix bugs before the user even knows there’s a problem.

    Topics:
    web dev ,angular ,components ,web application development

    Opinions expressed by DZone contributors are their own.

    {{ parent.title || parent.header.title}}

    {{ parent.tldr }}

    {{ parent.urlSource.name }}