• About Morris Development
  • A Focus for Cloud Efficiency
    • Microsoft Azure
    • Amazon Web Services
  • What our Clients Say
  • Our Products
    • PreschoolDB
    • WebinarDB
  • Contact Us

Morris Development

Custom System Development and Integration

September 21, 2016

Moving Data Between Angular 2 Components

As many people done, we’ve changed our Angular 1 sites to a component model, so we’re already familiar with how components work. Angular 2 is ALL components, and while it is quite similar, it has some interesting structures and some irritating ones. Primarily, the ease at which there were output variables {binding : “=”} is just plain gone. I knew that was coming, but from a business aspect, sometimes you just need to “get’er done” if you want to get paid! Here’s a simple tutorial of how we replaced the “=” binding that so easily let us connect objects between parents and children in angular 1.

Angular 2 uses @Input() and @Output() to move data and functions from one component to another. These actually use Classes, similar to how you might move data in C# from one function to another using a model. The “convention” is to have each class in a file by itself named after the class. In one of our systems, we have a person’s address, so we made an “Address” class like this:

/* file name ../classes/address.ts */
export class Address {
    address1: string;
    address2: string;
    city: string;
    state: string;
    zipcode: string;
}

Now, you can actually use it to import data from the outside world. It’s extremely easy. Instead of a “binding”, you simply put it in with your class-level variables. It’s a bit confusing at first, but here’s how it’s done and it makes sense after a while.

We start by telling the component that we’re actually going to do some importing & exporting of data by specfifically including that in the angular core import, just as you might have a “using” for system.data.sqlclient if you were doing some MS SQL work in your class.

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

Now, just as you may have a “using” statement at the top of your c# controller/class, you have to import that class, just as you would do to import a custom model in your c# using statement. You do it like this:

/* note, our file name is ../components/address/address.component.ts, so we just use a relative path to the class.  Later we might find a better way to do this, because I think it kinda sucks to hard-code this stuff. */

import { Address } from '../classes/address';

So, under that we have a component like this:

/* note:  we use this dynamic querystring in the URL while we develop to avoid caching */
@Component({
    selector: 'address',
    templateUrl: './app/address/address.component.html?v='+new Date().toUTCString()

})

Then, beneath that, we have our address class like this:


export class AddressComponent {
    @Input() address: Address;
    

    constructor() {}
    
}

now, to start with, let’s pretend that our @Input() address is just like : public address:any={“address1″:”123 some street”}. That object, however, is going to be coming from the “outside world”.

Got it so far? The @component sets the html element we use to call this component and tells us where it is (or you can put it right in there). Then we have a class that tells us that some or all of the data going into this element is coming from outside, which means, it’s going to be an attribute on the selector. So, we’d be writing it into another component’s html template like this:

Those brackets around address are pretty key. That means that the WhateverClassObjectNameYouDefinedAsAnAddress object is going to be sent into the address variable you defined in the @Import() of that component. In our case, it’s an object called “Address” (note: it converts attributes to lowercase)

So now, in your html template, you can use the object “address” (which is public by default) just as you would any variable in angular 1.

{{address.city}},{{address.state}} {{address.zipcode}}

That may seem like a lot, but it really isn’t all that big a deal when you come right down to it. You’re “using” an address model, you’re telling the class that it’s going to be getting that model full of data from a parent component, and then you’re using it.

Now that’s not to hard, right? Well, getting the data out is a pain in the ass. 🙂


kicking that data up to the parent component

This part is kind of a pain. I’d love it it did some kind of automatic push, but honestly, that is kind of inefficient and angular 2 is all about efficiency. So, how’s it done? With “emitters”.

In that example above, you might have noticed that I included the import of “EventEmitter”. That’s a tool that is used to populate an output variable and return it inside a function. (kinda weird if you’ve never done that before. javascript people love this)

Here’s that import, in case you don’t want to scroll up.

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

We’ll just send back the same address object, except now include our new data from some input boxes. First, you need to define your Emitter, just like you defined the @Import address: Address, you do this:

 @Output() addressUpdated: EventEmitter= new EventEmitter();

Notice, I include an interface definition of the Address class, not the actual address. You don’t need to do this, but it makes it nice and clean. (You should already know about interfaces if you are using typescript)

So, WTF is is an event emitter? Honestly, I only use one portion of it right now. the “emit” feature. Basically, it will execute a function in the parent. You call it with a function inside this component.

So, suppose you have a template like this:

  
Address1: City:

Ok, so that is going to fill out our address object with whatever is in those input boxes. Note the [(ngModel)]. That’s important. That’s like the ng-model=”address.address1″ in Angular1. However…. you HAVE to have the “name” attribute set too!! (that caught me for a bit when I was learning this!)

Now, you’ve got your little form set up, we’ve now got a button with a (click) attribute. This is the equivalent of ng-click=”update()”. So, we need a function in the component’s class that is named update(). The component class will look like this:


export class AddressComponent {
    @Input() address: Address;
    @Output() addressUpdated: EventEmitter= new EventEmitter();

    constructor() {}
    update() {
         // later you will see what this is for
        this.addressUpdated.emit(this.address);       
       
    }
}

So, we now have a normal function that can do whatever you want and THEN, it calls that “emit” function of the EventEmitter, which we have called addressUpdated, and we’ve populated it with the address object that we filled out in our form. Weird for some, but not really too complex. However, it is actually kind of sending that “function” rather than sending the data. So in our parent, we’re going to need to decide what “function” will be receiving this data and then the parent can do whatever it wants with it.

Our html in the parent component will look like this now.

Pretend that the $event object is just whatever data was in the “emit(SomeObjectInHere)” of the emitter on the child. The data from SomeObjectInHere will be contained in the $event object.

So your parent function would look like this:

WhateverFunctionWeWant(obj: IAddress) {
        console.log("Hey, I actually got the Address From the Child Component! ");
        console.log(obj);  // and here it is!  now I can do whatever I want with it.
        
    }

Personally, I think it’s a pain in the butt, HOWEVER, there are some benefits to it. First off, you can now easily trigger an event from a parent form. That could be handy. I mean, you don’t need to send any data at all! We like to keep our components pretty clean and have the “page” component, that we use to hold all the other components, manage the data to and from the database. So, if we want to get information to repopulate the sub component, like a chat list or something, then you can call the parent “update” function and tell it to repopulate the “listOfChats” object and never actually have the data being called from the chat component. That’s cool because we can then have 100 different chat formats and no duplication of database interaction code. (Stuff we tend to keep in the hands of senior developers with database access)

Still…. yeah, not easy as binding: {someattribute: “=”}. Seriously, that was uber easy. Conversion to the Emitter will be a bit irritating. However, we can actually emulate its functionality by making that update a bit more proactive:

City:

now, we’re sending the updated address object to the parent component as soon as we leave the field. We change that parent function to simply update the parent object (whatever we would have bound it to in angular 1). So, we have a few extra lines of code, but it’s almost the exact same thing but much more efficient (especially since Angular 1 was essentially doing that in the background with a key-up event)

Some Good References we used to learn these things

  • https://angular.io/docs/ts/latest/tutorial/toh-pt3.html
  • https://www.sitepoint.com/angular-2-components-inputs-outputs/
  • https://angular.io/docs/ts/latest/guide/dependency-injection.html
  • https://angular.io/docs/ts/latest/guide/forms.html
  • https://www.themarketingtechnologist.co/building-nested-components-in-angular-2/

[disqus]

Article by MacGyver / Angular 2, AngularJS, Web Developer

About MacGyver

I've worked with database systems for over 20 years, and started my own company in 2000. Almost all my business consists of internal database systems, either ERP or CRM. My programming is primarily in Angular / Microsoft C# and MS SQL.

About This Site

Morris Development has been specializing in internal database system design and integration since 1999. We provide long-term management and support of secure data systems for many businesses as well as developing the more complex code structures for ERP systems like Intellievent, Apidas, and AVMS.

This site is primarily for our developers to keep track up various technologies and updates that are used by Morris Development.

Training

Integrating Angular Microsite with .Net

Private Data Caching with Google Storage

Continuous Deployment for Production Releases?

Azure Websites – the perfect Angular host

Angular 2

  • Angular 2 Authentication
  • Angular Command Line Interface
  • Material Design for Angular
  • Using Observables in Angular 2

Mentors

  • Ben Nadel
  • Dan Wahlin
  • Deborah Kurata
  • John Papa

Staff

  • Dan Morris

Training

  • Google Development Courses
  • Microsoft Virtual Academy
  • PluralSight
  • Test Deep Links

© 2025 · Morris Development