An introduction to Angular EventEmitters

One use of an EventEmitter in Angular.io is for a child component to tell it’s parent something of interest has happened or to put it another way; they can be used to allow data to flow out of your component.

Below is a diagram of the application which I am going to be using in this post. It shows the parent (App-Root) and the child (App-Child) components. This post will build an application so that when something (in this case a button press) occurs in the child component the parent component should know about it.

When learning about EventEmitters I found it useful to understand the component hierarchy because without it I found it easy to become disorientated and end up not knowing what component needed to emit the event and which one needed to handle it.

Create a brand new application. If you get stuck or want to look at the completed example, it is up on GitHub.

ng new eventemitter-intro

Create a new component. I am using the short cut of g c (generate component) and spec = false to omit the testing file.

ng g c child --spec=false

The final step in setting up the application is to delete all the content from the app.component.html file and replace it with:


<app-child></app-child>

At this point your new Angular App should reflect the diagram with a parent component; app-root and a child; app-child and in Visual Studio Code looks like this:

Navigate to the child.component.html and add the following:

<p>  
<button>This button</button>
</p>
<p>
<button>That button</button>
</p>

Run your application using:

ng serve --open

You should see something similar to:

Now back to the child.component.html and add click events to the buttons:

<p>  
<button (click)="onButtonClicked()">This button</button>
</p>
<p>
<button (click)="onButtonClicked()">That button</button>
</p>

The click events are being bound to functions that have not been written yet so that will be the next step. Navigate to child.component.ts and change it so it now looks like this:

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

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

export class ChildComponent implements OnInit {
@Output() whichButton = new EventEmitter<void>();

constructor() { }
ngOnInit() { }

onButtonClicked() {
this.whichButton.emit();
}

}

The first change is:

@Output() whichButton = new EventEmitter<void>();

This line creates a new EventEmitter property called whichButton and is decorated with @Output(). To use the @Output decorator and the EventEmitter they are added to the import statement at the top of the file.

Next is the method that the click event on both of the buttons use. It invokes the emit method of the whichButton property.

At this point the child component now has been set up to emit an event each time one of it’s buttons is pressed. Now it’s on to the parent component to write the handler for this event.

Navigate to app.component.html and replace:

<app-child></app-child>

with

<app-child (whichButton)="whichButtonPressed()"></app-child>
<p>
{{ buttonPressed }}
</p>

So whenever there is a “whichButton” event emitted by app-child it will be handled by the whichButtonPressed method.

whichButton is the name of the EventEmitter property from the child component and whichButtonPressed() is the name of a method that will handle the event. This method hasn’t been written yet but will be in the next step. String interpolation will be used to display the name of the button that has been pressed.

Navigate to app.component.ts and add the following:

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

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

export class AppComponent {
buttonPressed: string;

whichButtonPressed() {
this.buttonPressed = (<HTMLButtonElement>event.currentTarget).innerText;

}

}

What is interesting here is that the code can access the event object without needing to pass it in as a parameter. If you want to find out more about the $event take a look at the Angular docs.

buttonPressed is a property that the string interpolation on
app.component.html will use to display which button has been pressed. This property is set by the method whenButtonPressed().

Here is the finished application showing the buttons that are on the child component and the result of pressing one of them being handled by the parent component.



Adding Bootstrap to your Angular App using VS Code

Introduction

In this how to guide, I will be adding Bootstrap 4 to an Angular 7 app using a Content Delivery Network (CDN)

Update 26/03/2019: This post has been replaces an earlier and incorrect version I had written on installing Bootstrap with Angular.

Prerequisites

In this guide I have used VS Code 1.32.3, Chrome 73, Angular 7, Bootstrap 4

Create a new Angular Application

First step is to create a new Angular app. So after starting VS Code and starting a new terminal session, run:

ng new bootstrap-cdn

Accept the defaults regarding Angular routing and style sheet format

Once the app has been created, run it to ensure it works.

Adding Bootstrap

With the skeleton of the Angular app in place using your favourite browser navigate to the Bootstrap home page and select Get Started.

You are then shown the CSS and Javascript CDN links:

Copy the CSS link and paste into the Angular index.html in the <head> section before all other stylesheets. Copy the JS links and paste them at the bottom of <body>. Your Index.html should now look like:

Save your changes.

Testing

Navigate to app.component.html and add a button with a Bootstrap class

 <button class="btn btn-primary"> 
This button is styled with Bootstrap </button>

You should then see the button, styled by Bootstrap appear on your page. If not press F12 and investigate any errors displayed.

My Angular development environment

Virtual Box

I use Virtual Box with Windows 10 as the Guest Operating System. It is a combination that works well and other than the usual Windows update dance, it doesn’t cause me any distractions. 

Visual Studio Code

All my Angular development have been built using Visual Studio Code which allows me to build, compile and run my projects without leaving the editor. I switched from Atom and I haven’t looked back. Using it is a joy and it allows me to focus on the task in hand. Superb Stuff. 

For Angular Development I am using the Gitlens, TSLint and Debugger for Chrome extensions

Chrome DevTools

I remember the relief I felt when a friend showed me Firebug for the first time. I was having a torrid time getting to the bottom of an opaque JavaScript problem. Fortunately Tools for the Web Developer have come a long way since then and I use the Chrome DevTools every time I work with Angular; from debugging my code to inspecting elements to see what Angular has welded on to them. The things you need most are shown whilst tools you use on lesser occasions are tucked neatly away with menus that make discoverability easy. 

I haven’t got any real experience of using the Firefox Developer Tools so if I am missing something useful please let me know in the comments.

Installed but not yet used: Chrome DevTools extension: Angular Augury

Angular Augury is an extension to Chrome that was recommended to me via the Udemy course I am taking. This extension is used for debugging and profiling your Angular Application. I haven’t had to use it yet so will revisit this post once I have some real world experience of using it.  

Err. That’s it. How does your development environment differ? What am I missing? 

The good, the bad and the ugly. Resources used as I teach myself Angular

I have spent many months this year learning Angular. More accurately I have wrestled with Angular, left to try React then decided that to get the most out of learning these frameworks I need to brush up on my vanilla JavaScript skills which I proceeded to do before finally returning to Angular. Phew!

I have used several resources to get up to speed with Angular and what I found useful and others that were not so are listed here. At the end of the post I ask for resources that have helped you learn Angular so if you don’t get that far please leave your recommendations in the comments

The good: Udemy Course

A friend recommended the Udemy course Angular – The Complete Guide by Maximilian Schwarzmüller. At the time of writing I am about half way through and it is the most enjoyable Angular resource I have found. Max is a friendly, enthusiastic teacher and the course is highly polished and easy to follow along building the sample applications and experimenting.

In addition to the discussions around language features there are lots of useful nuggets such as how to understand the opaque Angular errors that you are bound to see in your early days with the framework and the use of the browser add in Augury which is a very useful tool for debugging and profiling Angular applications.

The bad: ng-book

I have only purchased one book on Angular which was the eBook edition of the ng-book The print version was not available at the time. This is a large book running to 650+ pages. I didn’t enjoy it and only got as far as chapter 3 before giving up. Not sure why I didn’t enjoy it, perhaps I didn’t like the style or the fact that I prefer printed books? I lost patience by chapter three as the app wouldn’t work and I had no idea why. 


If you have a recommendation for an Angular book please do get in touch.   

The ugly: Official Docs

My adventures with Angular started with the Angular home page, I built the Tour of Heroes sample application and have wandered through the rest of the documentation look for other stuff to try out.

I have found the documentation to be dry and not a place that rewards you for spending much time there and so far I have had little reason to return. Problems that I encounter normally result in a Google search followed by a visit to the StackOverflow question.

Perhaps as my experience with the framework grows and I need to look things up I will be spending more time with the docs. If my opinion changes I will ensure that I update this post. 

Help needed

If you have Angular resources that you think may help me no matter how small please leave a comment. 

Fixed NG Book 5 Dependency Injection Page 175

I have been working through the NG2 book on Angular 5 and became stuck when trying to get an example on Dependency Injection to work.

Here is part of the problematic code I was unable to run:

ngDI-Copy

When running the sample, the page did not load and part of the console message reported by Chrome is shown below:

ngDI3-Copy

This problem was occurring using the following Angular environment:

ngDI2

Starting with the user-demo-component.ts file and after commenting out various parts of the code within this file I tracked the problem to the constructor:


constructor(private userService: UserService) {
}

Fortunately StackOverflow to the rescue and this answer provided the fix.  I made the following change to user-demo-component.ts whereby I added providers to the @Component decorator

...
  providers: [UserService]
...

The @Component decorator should now look like this:

ngDI4-After

Why does the completed example work without this fix?

Good question! If you have read any of NG2 book you will know that all the code examples in the book come with the source ready for you to try out rather than typing. When I checked the example and ran them I couldn’t see a similar change yet the code worked as expected so I will need to continue digging to ascertain why the supplied version works.

I will update the post once I have found out.

Update 23/04/2018

The completed example uses a different version of Angular and typescript. Here is the output from ng –version

ngDI5-After-Copy

The completed example which works uses Angular 5.2.0 whereas the version of Angular I am using is 5.2.9.