A5 — Angular Series : Dependency Injection, Input, Output, two-way-binding

Sourabhh Sethii
DXSYS
Published in
8 min readMay 19, 2020

DXSYS(Digital Experiences & Systems), welcome you all to Fifth article of angular series. Let’s recap all the concepts we have gone so far.

A1.) Create A Project — You can check article on creating the project. Click Here.

A2.) Create A Component — You can check the article on creating a component . Click Here.

A3.) Manage-Events — You can check the article on managing basic events such as click. Click Here.

A4.) Handle Events, Share Services, Dependency-Injection — You can check the article on DI, Share Services. Click Here.

We will look into below topics in detail

1) Dependency Injection

2) Pass Values Into Components With Input

3) [(ngModel)] Two-way Binding

4) Pass Events Components With Output

Dependency Injection

In last article of this series, I have already introduced you with DI(Dependency Injection), Here we will look this topic more in detail. Dependency injection (DI), is an important application design pattern.

For any dependency that you need in your app, you must register a provider with the app’s injector, so that the injector can use the provider to create new instances. For a service, the provider is typically the service class itself.

@NgModule({

declarations: [ AppComponent, SampleFormComponentComponent ], imports: [ BrowserModule, AppRoutingModule, FormsModule ],

providers: [{ provide : ‘sharedservices’, useClass: SharedServiceService}, {provide: ‘sharevalue’, useValue : ‘Shared text!’}], bootstrap: [AppComponent]})

export class AppModule { }

Module File @ : https://github.com/Sourabhhsethii/Let-Us-Start-With-Angular/blob/master/Angular-Series-A5-ngfor-input-output-two-way-binding/src/app/app.module.ts

When Angular creates a new instance of a component class, it determines which services or other dependencies that component needs by looking at the constructor parameter types. For example, the constructor of SampleFormComponentComponent needs SharedServiceService as shown in below sample code.

import { Component, OnInit, Inject, Input, Output, EventEmitter, NgModule } from ‘@angular/core’;

@Component(

{ selector: ‘app-sample-form-component’, template: ` <p style=”color: red”> {{sharedservices.message}} </p> <div style=”color: green”>{{sharevalue}}</div> <div style=”color: blue”>{{message}}</div> <input #myIput type=”text” [(ngModel)] = “message”> <button (click)=”update.emit({text:message})”> click Me!</button> `, styles: [ ]

})

export class SampleFormComponentComponent implements OnInit

{

@Input() message = ‘’;

@Output() update = new EventEmitter();

/* the constructor of SampleFormComponentComponent needs SharedServiceService*/

constructor( @Inject(‘sharedservices’) public sharedservices, @Inject(‘sharevalue’) public sharevalue) { } ngOnInit(): void { }

}

Component File @ : https://github.com/Sourabhhsethii/Let-Us-Start-With-Angular/blob/master/Angular-Series-A5-ngfor-input-output-two-way-binding/src/app/sample-form-component/sample-form-component.component.ts

Registering Services in Provider

The provider can be part of the service’s own metadata, making that service available everywhere, or you can register providers with specific modules or components. Three Way to register the services are as follows:

1.) You register providers in the metadata of the service (in the @Injectable() decorator),

2.) @NgModule()

3.) @Component() metadata

By default, the Angular CLI command ng generate service registers a provider with the root injector for your service by including provider metadata in the @Injectable() decorator. The tutorial uses this method to register the provider of HeroService class definition.

@Injectable({ providedIn: ‘root’, })

Registering the provider in the @Injectable() metadata also allows Angular to optimize an app by removing the service from the compiled app if it isn't used

When you register a provider with a specific module, the same instance of a service is available to all components in that NgModule. To register at this level, use the providers property of the @NgModule() decorator,

@NgModule({

declarations: [ AppComponent, SampleFormComponentComponent ], imports: [ BrowserModule, AppRoutingModule, FormsModule ],

providers: [{ provide : ‘sharedservices’, useClass: SharedServiceService}, {provide: ‘sharevalue’, useValue : ‘Shared text!’}], bootstrap: [AppComponent]})

export class AppModule { }

When you register a provider at the component level, you get a new instance of the service with each new instance of that component. At the component level, register a service provider in the providers property of the @Component() metadata.

@Component(

{ selector: ‘app-sample-form-component’,

templateUrl: ‘./app-sample-form-component.html’,

providers: [ SharedServices]

})

Services are singletons within the scope of an injector. That is, there is at most one instance of a service in a given injector.

There is only one root injector for an app. Providing UserService at the root or AppModule level means it is registered with the root injector. There is just one UserService instance in the entire app and every class that injects UserService gets this service instance unless you configure another provider with a child injector.

You learned the basics of Angular dependency injection in this article. You can register various kinds of providers, and you know how to ask for an injected object (such as a service) by adding a parameter to a constructor.

Two way binding

We will also look two way binding in detail in this article but before that we need to understand the data binding.

DATA BINDING

In Angular, data binding determines how data will flow in between the component class and component template.Angular provides us three types of data bindings:

1. Interpolation

2. Property binding

3. Event binding

Data Binding

INTERPOLATION

Angular interpolation is one-way data binding. It is used to passdata from the component class to the template. The syntax of interpolation is {{propertyname}}.

In below example sharevalue and message object are binded Using interpolation, data is passed from the component class to the template. Ideally, whenever the value of the objects is changed, the template will be updated with the updated value of the object. Therefore, if you want to display data in Angular, you should use interpolation data binding.

Template: -

<div style=”color: green”>{{sharevalue}}</div>

<div style=”color: blue”>{{message}}</div>

Component Class :-

export class SampleFormComponentComponent implements OnInit {

@Input() message = ‘’;

@Output() update = new EventEmitter();

constructor(

@Inject(‘sharedservices’) public sharedservices,

@Inject(‘sharevalue’) public sharevalue) { }

ngOnInit(): void {

}

}

PROPERTY BINDING

Angular provides you with a second type of binding called property binding. The syntax of property binding is the square bracket: []. It allows for setting the property of HTML elements on a template with the property from the component class.So, let’s say that you have a component class like the one below:

@Component({

selector: ‘app-root’,

templateUrl: ‘./app.component.html’,

styleUrls: [‘./app.component.css’]

})

export class AppComponent {

title = ‘Angular-Series-A5-ngfor-input-output-two-way-binding’;

@Output() update = new EventEmitter();

constructor(

@Inject(‘sharedservices’) public sharedservices){

}

onUpdate(id, text){

this.sharedservices.update(id, text);

}

}

Angular property binding is used to set the property of HTML elements with the properties of the component class as shown below.message.text is binded with [message].Whenever the property’s value in the component class changes, the HTML element property will be updated in the property binding.

<ul>

<app-sample-form-component *ngFor=”let message of sharedservices.messageObject

[message]=”message.text” (update)=”onUpdate(message.id, $event.text)” ></app-sample-form-component>

</ul>

EVENT BINDING

Angular provides you with a third type of binding to capture events raised on templates in a component class. For instance, there’s a button on the component template that allows you to call a function in the component class. You can do this using event binding. The syntax behind event binding is (eventname). For Example above example (update). We want to call onUpdate(message.id, $event.text) function on the click of a button on the template. You can do this using event binding:

(update)=”onUpdate(message.id, $event.text)

Angular provides you these three bindings. In event binding, data flows from template to class and in property binding and interpolation, data flows from class to template.

Bindings

Angular does not have built-in two-way data binding; however, by combining property binding and event binding, you can achieve two way data binding.Angular provides us a directive, ngModel, to achieve two-way data binding, and it’s very easy to use. First, import FormsModule, and then you can create two-way data binding:

Two Way Binding

<input #myIput type=”text” [(ngModel)] = “message”>

As you see, we are using [(ngModel)] to create two-way data binding between input control and name property. Whenever a user changes the value of the input box, the name property will be updated and vice versa.

COMPONENT COMMUNICATION

We will look into brief on component communication as well, In Angular, components communicate to each other to share data such as object, string, number, array, or HTML.

To understand component communication, first, we need to understand relationship between components. For example, when two components are not related to each other, they communicate through an Angular service.

When you use a component inside another component, you create a component hierarchy. The component being used inside another component is known as the child component and the enclosing component is known as the parent component. As shown in the image below, in context of AppComponent, app-child is a child component and AppComponent is a parent component. Parent and child components can communicate to each other infollowing ways:

• @Input()

• @Output()

• Temp Ref Variable

• ViewChild

• ContentChild

@INPUT

You can pass data from a parent component to a child component using the @Input decorator. Data could be of any form such as the primitive type’s string, number, object, array, etc.

@OUTPUT

You can emit the event from the child component to the parent component using the @Output decorator.

We will look into @INPUT and @OUTPUT in detail in next article. Stay tuned.

You can also refer Angular Documentation :

https://angular.io/guide/architecture-services

https://angular.io/guide/dependency-injection

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

Repository : You can clone below repository and run the application to check the demo.

https://github.com/Sourabhhsethii/Let-Us-Start-With-Angular/tree/master/Angular-Series-A5-ngfor-input-output-two-way-binding

Output Screen:

Interview Questions :

Question 1.) What Is DI?

Question 2.) What is Injector?

Question 3.) How services are Injected and provided to Components?

Question 4.) What is Two Way Binding and How it is achieved in angular 2 and above?

Question 5.)What is Event Binding?

Question 6.)What is Property Binding?

Question 7.)List different type of binding?

Question 8.)How communication happens between the components?

--

--

Sourabhh Sethii
DXSYS
Editor for

I am an author of Building Digital Experience Platform and I am passionate about emerging technologies. https://sourabhhsethii.com/