Moving between projects that use NPM and Yarn typically isn’t a big deal. For the most part, the package dependency managers work almost identical. But one thing that does tend to trip developers up is the subtle command line changes between the two. Often it’s just the case of swapping install/uninstall in NPM to add/remove in Yarn, so here’s a quick cheatsheet for doing just that.

NPM Command Yarn Command Description
npm install [package-name] yarn add [package-name] Installs a package
npm install [package-name] –save-dev yarn add [package-name] –dev Installs a package as a dev dependency
npm install yarn OR yarn install Installs all dependencies inside package.json
npm uninstall [package-name] yarn remove [package-name] Uninstalls a package
npm uninstall [package-name] –save-dev yarn remove [package-name] Uninstalls a package as a dev dependency (Yarn command is the same as uninstall regular dependency)
npm update yarn upgrade Updates all packages
npm update [package-name] yarn upgrade [package-name] Updates a single package
npm install [package-name] -g yarn global add [package-name] Installs a globally accessibly package
npm uninstall [package-name] -g yarn global remove [package-name] Uninstalls a globally accessibly package

While the above are the main commands that have subtle differences. There are actually some commands that are identical between NPM and Yarn, that you basically just sub out the word npm with yarn on the command line and you are good to go. These are :

NPM Command Yarn Command Description
npm install –production yarn install –production Installs all dependencies in package.json *except* dev dependencies
npm init yarn init Creates a new package.json file / project setup
npm run yarn run Runs scripts from your package.json file
npm test yarn test Runs tests from your package.json file
npm publish yarn publish Publishes your package/td>
npm cache clean yarn cache clean Clears the global package cache
npm login yarn login Logs a user into an package register

Importing Lodash into your Angular project may be slightly controversial in some circles, but I often find myself adding it (and adding the few KB that comes along with it), rather than reinventing the wheel in each project. If you’ve never used it before, Lodash is a javascript library that provides handy data manipulation extension methods for arrays/collections. If you’ve used C# LINQ, you’ll probably be familiar with many of the methods like OrderBy, GroupBy, Join etc. It’s also important to note that it pays to check if the default Array type in Javascript has what you need as there is a little bit of overlap (For example Find exists on both an array and Lodash).

But that’s not all! One of the most common use cases for Lodash is actually manipulating objects that aren’t arrays. For example, an extremely common use-case for me is using the _.clone() method which copies all the values of an object into a new object that’s safe for editing. This is extremely common for me when I’m doing two way data binding on a form that a user can “cancel”, so I still have the original object in tact.

In anycase, this post isn’t a pros and cons guide to using Lodash, it’s about adding it to your Angular project, so let’s get on and do that!

Adding Lodash To Angular

The first thing you want to do is add the Lodash package to your project using NPM/Yarn.

NPM

npm i lodash --save

Yarn

yarn add lodash

This adds Lodash to our project and at this point is ready for use, but it’s just the raw library. What we also need is the type definitions to give us some nice strongly typed defintions inside Typescript. For that we need to install one more package.

NPM

npm i --save-dev @types/lodash

Yarn

yarn add @types/lodash --dev

Note that we only add the type definitions as a dev dependency as it is not required at runtime, only while you are developing your project.

Anywhere in your project, you should now be able to import Lodash like so :

import * as _ from 'lodash';

let myItem = {};
let clonedItem = _.clone(myItem);

If you’re coming from a language such as Java or C#, the concept of constructor overloading is a pretty common one. But as a refresher in say C#, we can overload constructors like so :

class MyClass
{
	public MyClass(string value)
	{
		this.value = value;
	}
	
	public MyClass(int value)
	{
		this.value = value.toString();
	}

	private string value;
}

Whereby we create two different constructors, that take two very different parameters, to construct our object. It should also note that in C#, there is no limitation on how different these constructors can be. For example you can even have a different number of parameters :

class MyClass
{
	public MyClass(string value)
	{
		this.value = value;
	}
	
	public MyClass(string first, string second)
	{
		this.value = first + second;
	}

	private string value;
}

In Typescript/Angular, things aren’t so easy. If we tried the above code in Typescript such as :

export class MyClass
{
	constructor(value : string)
	{
		this.value = value;
	}
	
	constructor(value : number)
	{
		this.value = value.toString();
	}

	private value : string;
}

You will get the following error :

Module parse failed: Duplicate constructor in the same class 

You’ll probably also see something like :

error TS2392: Multiple constructor implementations are not allowed.

But you’ve heard that Typescript *does* support constructor overloading, so what gives? Why doesn’t this work.

Overloading Constructors In Typescript

Overloading in Typescript is a little different to what you might expect, while you can overload constructors, you cannot have multiple implementations. What this means in practice is that you either can create a union type such as :

export class MyClass
{
	constructor(value : string | number)
	{
		this.value = value.toString();
	}

	private value : string;
}

Where the constructor can accept one of either types, and you handle both within the same implementation. In this example we can handle both easily because calling toString() on a string is a safe operation, but otherwise you have to resort to using typeof checks :

export class MyClass
{
	constructor(value : string | number)
	{
		if(typeof value === "string")
		{
			this.value = value;
		}

		if(typeof value === "number")
		{
			this.value = value.toString();
		}
	}

	private value : string;
}

Honestly for me, this just looks like a mess and is hardly worth the hassle.

It get worse (just in my opinion), when you want a differing amount of parameters for two different constructors. What you need to instead do is create a single implementation that each constructor can “fall down” to the next without breaking. For example :

export class MyClass
{
    constructor(value : string)
    constructor(first : string, second? : string)
    {
        if(!second)
        {
            this.value = first;
        }else 
        {
            this.value = first + second;
        }
    }

    private value : string;
}

The constructor with a single “value” is able to fall down to the second constructor because the second parameter is nullable. We can determine which constructor was used by checking if the second value is set or not.

Again, less than ideal. I find the biggest issue is as you add constructors, removing one in the “middle” of the list suddenly breaks everything. In my opinion, this way of overloading constructors in typescript is extremely brittle and prone to giving developers headaches.

A Better Way With Static Factories

Because of the way constructor overloading works, it can be hard to wrangle if you have wildly different constructor implementations depending on the parameters. For this reason I use a simple  static factory pattern.

export class MyClass
{
    static fromSingleValue(value : string) : MyClass {
        var result = new MyClass();
        result.value = value;
        return result;
    }

    static fromTwoValues(first : string, second : string) : MyClass {
        var result = new MyClass();
        result.value = first + second;
        return result;
    }

    private value : string;
}

Now I can just call MyClass.fromSingleValue(‘something’) to get a class constructed for me. Better yet, any developer looking at this will find it extremely easy to follow, even if they’ve never used Typescript before.

Where static factories really come into their own is when you are consuming an entire other object :

export class MyOtherClass
{
    public value : string;
}

export class MyClass
{
    static fromSingleValue(value : string) : MyClass {
        var result = new MyClass();
        result.value = value;
        return result;
    }

    static fromTwoValues(first : string, second : string) : MyClass {
        var result = new MyClass();
        result.value = first + second;
        return result;
    }

    static fromMyOtherClass(myOtherClass : MyOtherClass) : MyClass {
        var result = new MyClass();
        result.value = myOtherClass.value;
        return result;
    }

    private value : string;
}

Now adding and removing constructors does not break any other constructor, and they all act independently from one another.

Detecting clicks on a particular component/element that you have complete control over is fairly trivial in Angular, but what about if you want to know when a user clicks somewhere on the page on something that is *not* inside a particular component. It may sound like a weird edgecase but it’s actually really common when building things like custom popup modals or even just custom dropdown/select controls. With these you often want to detect if a user clicks away from the component so that you can hide the modal/popup or slide up the dropdown control.

I couldn’t find anything really talking about this particular issue but as it turns out, it’s pretty easy to get up and running!

Let’s assume I have a component called “DropDownComponent” that I want to detect if there are clicks *outside* of this control. Basically if there is a click anywhere else on the webpage. The first thing we have to do, is inject a reference to ourselves in the constructor.

constructor(private elementRef: ElementRef) {
}

When ElementRef is injected this way, Angular injects in the HTML native element that this component is drawn into, which is perfect for us because now we know in plain javascript/html, what our element is referenced as.

The next piece of the puzzle is actually very trivial. Inside our component we add a HostListener that listens for any document:click.

@HostListener('document:click', ['$event.target'])
public onPageClick(targetElement) {
  const clickedInside = this.elementRef.nativeElement.contains(targetElement);
  if (!clickedInside) {
	//Do something. 
  }
}

The code itself is pretty self explanatory. We detect any document clicks (Which is a click anywhere on the page), and in doing so, we detect exactly what element was clicked. Next we determine if the element that was clicked lives inside our component by using the injected ElementRef we put in the constructor, if it doesn’t, then bingo, we know that the user has clicked outside of the component and we can run whatever custom code we wish to (e.g. Close the modal, slide up the dropdown list etc).

This probably looks a little heavy handed (And it is really… ), but a good thing to note is that HostListeners are destroyed when the component they belong to is destroyed. So unless you attach this to every single component, you’ll generally only have 1 or 2 of these document click listeners running at any one time.

I was working with a piece of code recently that made liberal use of the “Tap” operator on an observable. I’ve seen it used pretty often, but everytime I try and find documentation to show a junior developer how it works, I always find it a really overcomplicated mess. Tap, infact, is a really simple operator on the surface that you really shouldn’t have a hard time understanding.

Let’s jump straight into some code. The most common use-case for using tap is because you want to use the result of an observable elsewhere, but still pass the exact same result back to any subscriber.

For instance let’s say that I want to call an API to fetch the current user, and I want to do nothing more than log that user to the console, and then return that same user out. A very naive way to achieve this would be :

this.http.get<User>('api/user').pipe(map((user : User) => {
	console.log(`Current User Is : ${user.name}`)
	return user;
}));

Theoretically not a heck of a lot wrong with this, I mean it works, but it’s not nice. You are calling the map function purely so that you can log the user, but then you aren’t actually mapping anything, and instead returning the same user. The result of this function is still Observable<User> so the caller doesn’t know what’s going on behind the scenes, but it’s messy.

One of the worst ways I’ve seen someone try and achieve this looked like so :

return Observable.create((observer: Observer<User>) => this.http.get<User>('api/user').subscribe((user : User) => {
	console.log(`Current User Is : ${user.name}`)
	observer.next(user)
	observer.complete()
}));

I mean talk about RxJS word salad. It’s a mess. And we don’t need to do this if we just use Tap!

Taking the above example and using Tap.

this.http.get<User>('api/user').pipe(tap(user => { 
	console.log(`Current User Is : ${user.name}`) 
}));

Notice how we used tap to write the console log, but we didn’t have to return the user object. It’s because we are saying that Tap will do something with the user object, but the original user should be returned to whoever is subscribing.

Another way to remember what tap does is that you are “tapping” into the result. Like a wiretap almost! You are listening in but (theoretically), you aren’t interfering with the existing conversation.

There is one caveat when using Tap though, and that is that the object inside the tap is still a reference to the original, it’s not a clone. So for example :

//This will return a user object with the firstName of test. 
this.http.get<User>('api/user').pipe(tap(user => { 
	user.firstName = 'Test';
}));

I personally prefer to use Tap only when the method inside the tap is safe and has no side effects that would alter the original result. If I am going to be altering the original result, I prefer to use the Map operator because that signals that we are “mapping” what the original result was to something new (Even if it’s only changing a single property).

A common issue when adding a required attribute to a textbox/textarea in an Angular application is that someone can just press space bar once, and the “required” validation is completed. A space counts as character!

The simple way to get around this is to use a regex pattern attribute to validate that there is more than just a space. Something like :

<input type="text" pattern="^(?!\s*$).+" />

But this quickly gets annoying to copy and paste everywhere. A better solution if you need to validate multiple fields the same way is to create a nice directive. Here’s one I prepared earlier :

import { Directive } from '@angular/core';
import { NG_VALIDATORS, Validator, ValidationErrors, AbstractControl } from '@angular/forms';

@Directive({
  selector: '[noWhitespace]', 
  providers: [{ provide: NG_VALIDATORS, useExisting: NoWhitespaceDirective, multi: true }]
})
export class NoWhitespaceDirective implements Validator {

  constructor() { }

  validate(control: AbstractControl): ValidationErrors {
    if(!control.value || control.value.trim() == '')
    {
      return {'required' : true };
    }

    return null;
  }

}

Simply place this on any text input/area control like so :

<input type="text" noWhitespace />

And you will now validate that the control has a value *and* that the value is not just whitespace. Easy!

I came across an interesting challenge recently that involved being able to pass a “template” between components. In my particular case, I had a “table” component that simply laid out tabular data, nothing too crazy. In most cases I simply wanted the text value of a property to be displayed, but in some rare cases, I needed a custom template to be shown. While it may seem simple, simply pass through a string variable with HTML inside and be done with it, when it comes to data binding, it actually becomes a bit more complex than that.

I quickly came across TemplateRef in the Angular documentation which sounded like what I needed, but as is the case with many Angular internals, the documentation was somewhat lacking. So let’s explore TemplateRef and see what it can actually do.

The Basics

The basics to actually get a “TemplateRef” variable in the first place looks like so. Let’s say I create a component called “ParentComponent”. I’m going to create the HTML (thus far) looking like so :

<ng-template #myTemplate>
    <h1>This is my Template</h1>
</ng-template>

All this is doing is creating a “template” object called #myTemplate. This actually doesn’t render anything to the page, it simply tells Angular that at some point, you will use this template somewhere. I think it’s probably pretty similar to Handlebars templating if you’ve ever used that before.

Now the code behind our component will be very simple.

export class ParentComponent implements OnInit {

  @ViewChild('myTemplate', {static : true}) myTemplate : TemplateRef;

  myModel = {
  };

  constructor() { }

  ngOnInit() {
    this.myModel =  {
      template : this.myTemplate
    }
  }

}

So all we are doing here is using ViewChild to get a reference to the actual template and storing it in a TemplateRef variable. I’m also creating a “model” object. Although you don’t have to do this, from my MVC days I prefer creating a “ViewModel” to pass between components. In our case we want to create a second component to accept this template.

So I’m going to create a component called ChildComponent. The code behind the component looks like so :

export class ChildComponent implements OnInit {
  
  @Input() model : any;

  constructor() { }

  ngOnInit() {
  }

}

It will accept an input of “any” which in our case will be our model we created in our ParentComponent. Really I should create a proper strongly typed class here but for now, the type of any will suffice.

For the HTML of our child component, we then need to do the following :

This is my child component. <br />

<ng-container *ngTemplateOutlet="model.template"></ng-container>

What we are doing here is outputting an ng-container that is given a template (The template we passed through) to render.

If we go back to our ParentComponent and add the child tag to it so the HTML ends up looking like :

<ng-template #myTemplate>
    <h1>This is my Template</h1>
</ng-template>

<app-child [model]="myModel"></app-child>

Run everything and wham! Our template is passed through to our child component that renders it perfectly!

Why Not Use NG-Content?

So another way to achieve this is using the <ng-content> tag which we will definitely talk about in another post. But if a developer is asking you why not just use that? Well… After using it for a while I’ve found that the ng-content tag is great for single projections, but if you are wanting to pass multiple templates into a component ng-content is a little bit more rough around the edges on how that works. The other thing I found was that the data binding was no where near as intuitive in ng-content as it is using ngTemplateOutlet.

Databinding?! You can do that?! You sure can. Let’s take a look at hot it works.

Databinding NgTemplateOutlet

A very common scenario for templates is that you will want to databind values inside the actual template. The issue with this is, what is it binding to? In our example above, if we added data bindings to our template would it be binding to the ParentComponent since that’s where the template is defined, or would it bind to the ChildComponent because that’s where the template is actually output?

The answer is neither. It doesn’t bind at all unless you specify where it should bind and to what.

Let’s modify our template to bind a subheading. The way to make this work looks like :

<ng-template #myTemplate let-data="data">
    <h1>This is my Template</h1>
    <h4>{{data.subheading}}</h4>
</ng-template>

So you’ll notice we do a “let” command above. What that says is, I’m going to be passed a value called “data” (That’s the data actually inside the quotes), when I’m given that, bind it to a variable called “data” that is scoped to this template.

Then below, I will expect on this data object to be a subheading property.

Go back to our ParentComponent and change how we bind the model to also have a subheading property :

ngOnInit() {
  this.myModel =  {
    template : this.myTemplate, 
    subheading : 'this is my subheading'
  }
}

Because we are still passing through our model to the child component, the binding and codebehind there stays the same. But inside the actual HTML of the ChildComponent we have to tell it the context we want to give it. We do that like so :

This is my child component. <br />
<ng-container *ngTemplateOutlet="model.template; context: { data : model}"></ng-container>

So notice on the *ngTemplateOutlet, we pass in a context. Now personally, I like to create another “sub” object with a key value like this. This means that you can pass in multiple values on the same object etc, but it’s up to you.

Now when our template is run, it knows about this object called “data”, and can use that to bind values. Super easy!

I have a pretty easy rule when it comes to using NG-Deep on my projects, “if you think you need it, I would think a little harder”. 9 times out of 10 when I see people using the ng-deep modifier, it’s because they want a “quick fix” without really thinking through the consequences. And in the majority of those cases, the use of ng-deep comes back to bite. I want to talk a little more about NG-Deep “bleeding”, and how the lazy loading of styles in Angular often hides the issue until things are already in production.

What Is NG-Deep?

NG-Deep is essentially a CSS pseudo element that allows you to “break” CSS encapsulation. For example let’s say that I have a very simple component like so :

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

@Component({
  selector: 'app-first-parent',
  template: `<app-child></app-child>`,
  styles : ['h1 { color:red; }']
})
export class FirstParentComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

Notice a couple of things, that the template is simply a component called “child”, and on this particular page, I want all H1 tags to be red. Well you may think that if I create the child component like so :

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

@Component({
  selector: 'app-child',
  template: `<h1>This is a child component</h1>`,
  styles: []
})
export class ChildComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

We might at first suspect that the H1 tag is going to be red. But if we view it in a browser, it doesn’t work!

When we check the page source for our styling, we can see it looks like so :

h1[_ngcontent-iqb-c1] { color:red; }

The _ngcontent is our view encapsulation taking hold. Because we have put our H1 styling into our FirstParent component, it’s limited that styling to *only* that component. Because our H1 is actually in a child component, we are a bit shafted.

But hold on, we’ve heard about this amazing thing called ng-deep that basically removes encapsulation for components in Angular! Let’s try it!

If we change the styling of our FirstParent component from :

styles : ['h1 { color:red; }']

To :

styles : ['::ng-deep h1 { color:red; }']

Does everything work?

It does! And when we check the source code we can see that the styling has had the view encapsulation removed and it’s just a plain h1 style now!

<style>h1 { color:red; }</style>

So everything works right?

Adding Another Component

Let’s add another component that’s almost identical to the first. We’ll call it “SecondParent”.

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

@Component({
  selector: 'app-second-parent',
  template: `<app-child></app-child>`
})
export class SecondParentComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

This one is identical to the first, except that we don’t have any styling for our H1s. We instead just want to use the default styling.

We will also add some routing so that if we go to /firstparent, we are taking to the FirstComponent, and /secondparent goes to the second. The routing looks like so :

const routes: Routes = [
  { path : 'firstparent', component : FirstParentComponent}, 
  { path : 'secondparent', component: SecondParentComponent}
];

For this to work, we want a button on the FirstParent that goes to the Second, and vice versa. To make things easier for ourselves, we want to change the FirstParentComponent to have the following template :

template: `This is the first parent. <br /><app-child></app-child> <a [routerLink]="['/secondparent']">Go To Second Parent</a>`

And the SecondParentComponent should have :

template: `This is the second parent. <br /><app-child></app-child> <a [routerLink]="['/firstparent']">Go To First Parent</a>`

While theoretically the template changes aren’t needed, for this next little demo it will make things easier to see.

Let’s try a couple of straight navigation options.

If I go directly to /firstparent, I see :

This is correct. We get the red H1 tag.

If I go directly to /secondparent (By direct I mean typing it in my browser and not clicking the link), I see :

Also correct, we have the black H1 and not the red. Perfect!

Let’s try something else, if we go directly to /firstparent, then click the link to go to the SecondParent, what happens?

So.. When we go direct to /secondparent, everything works fine, but if we go to /firstparent, then navigate via Angular to the /secondparent, it all goes wrong. Why?

Well it’s actually a simple explanation.

CSS in Angular is LazyLoaded, that means that any styles for a particular component are only actually loaded when that component is itself loaded. For us that means that we only get our special ng-deep rule when FirstComponent is actually loaded, but if we go direct to the SecondComponent from our URL bar, then it doesn’t need to load that CSS and so doesn’t.

The reason I want to point this out is because in the majority of cases where I see ng-deep go wrong, it’s been incredibly hard to track down bugs where sometimes you have to go through a series of pages to recreate the bug. In our example, imagine if a tester/QA logged a bug that said when they went to /secondparent, the text was red. Well if we just tried to recreate it by going directly to that page, we wouldn’t see the issue!

At the crux of it though, we see that using ng-deep the way we have done causes big issues because we are essentially writing an H1 rule to the global stylesheet. It’s the exact issue that view encapsulation tries to fix, but then gives us the tools to wreck it anyway.

Working Without NG-Deep

Let’s look at some ways to work without NG-Deep, or more so ways in which we can limit our exposure to bugs like above.

Using :host

First up is my favourite, and one that Angular actually recommends, and that’s prepending any ng-deep rule with the :host modifier. We have a great article on how to use :host here! But in simple terms, if we change our rule inside FirstComponent to look like so :

styles : [':host ::ng-deep h1 { color:red; }']

What we are essentially saying is that we still want to go “deep”, but only when we are inside this particular component. The rule itself when written to the page looks like :

[_nghost-qxj-c1] h1 { color:red; }

Where the _nghost is the FirstComponent, and it’s saying any H1s inside this component can be red, but any H1s inside any other component will not be affected.

Being More Specific

If for some reason you don’t want to use :host (Or can’t), then another option is to simply be more specific in your rules that are going to be global. For example if we changed our template and styling inside FirstParent to look like so :

template: `This is the first parent. <br /><div class="first-parent-wrapper"><app-child></app-child></div> <a [routerLink]="['/secondparent']">Go To Second Parent</a>`,
styles : ['::ng-deep .first-parent-wrapper h1 { color:red; }']

So notice how we have now wrapped our child control in a very specific class, that we can then use for our styling. Even though this rule will be global, it’s unlikely (But not impossible), that someone somewhere else uses the same “first-parent-wrapper” class. But again, you are essentially breaking view encapsulation and banking that no one else uses this class name anywhere else.

Passing Variables

Of course the final option, which should be pretty obvious,  is that you can ofcourse pass styles or even switches to a child component. So you can create an input parameter for your child component called “headerText”, and then pass in the color you want it to be. This does have it’s limits though in that generally you are looking for a direct parent to child relationship, and you don’t want to be passing around styling several layers deep. But it’s an option!

Work Without It

This isn’t really a solution but one that always pays to keep in mind. Use of NG-Deep should be a last resort. It should be used when you really can’t find any other way to achieve what you are doing. You’ve asked on stackoverflow and on the Angular Github tracker, and there’s just no other possible way to do things without NG-Deep. Even then, you should use one of the above methods to limit your exposure.

This article is part of a series on creating multi step form wizards in Angular.

Part 1 – Basic Setup
Part 2 – Building Our Forms
Part 3 – Tying It All Together


We are on the home stretch with our multi-step form, infact we are pretty much there! But I wanted to give a few more tips on tying everything together, including an awesome debugging trick.

The Final HTTP Post

Having a form is useless unless it actually sends data, and luckily for us, we already have a service prepared to do just that – our FormDataService! At the moment it looks like :

export class FormDataService{

  personalDetails : PersonalDetails;
  addressDetails : AddressDetails;

  constructor() {
    this.personalDetails = new PersonalDetails();
    this.addressDetails = new AddressDetails();
   }
}

Our best bet is to add a simple “postData” method that collates everything together and talks to some backend API (Not features). For example :

export class FormDataService{

  personalDetails : PersonalDetails;
  addressDetails : AddressDetails;

  constructor() {
    this.personalDetails = new PersonalDetails();
    this.addressDetails = new AddressDetails();
   }

   postData(){
     let newCombinedObject = {
       personalDetails : this.personalDetails, 
       fullAddress : this.addressDetails.fullAddress
     }

     //Use somthing like http.post etc to send the data to the backend server. 
   }
}

I know that this is a bit of a simplistic view, but it’s hard to get into the nitty gritty without also building out an actual API. The point I want to make here though is that we have all the models from all the different steps of the form, we can take all of that data and mould it into our API model. In my case, I have taken the full personalDetails object, but from the address I’ve taken out the individual property. It’s up to you to transform the data how you need it, but the idea is that it’s all there to play with!

Heading back to our Address Details component, if we add in a click event handler to our backend :

export class AddressDetailsComponent implements OnInit {

  addressDetails : AddressDetails;

  constructor(private formDataService : FormDataService) { 
    this.addressDetails = formDataService.addressDetails;
  }

  ngOnInit() {
  }

  submit(){
    this.formDataService.postData();
  }

}

And then bind our HTML to that click event handler :

<table>
    <tr>
        <td>Full Address</td>
        <td><input type="text" [(ngModel)]="addressDetails.fullAddress" #fullAddress /></td>
    </tr>
    <tr>
        <td><input type="button" value="Back" routerLink="" /></td>
        <td><input type="button" value="Complete" (click)="submit()" /></td>
    </tr>
</table>

And we have a full complete submit routine!

Debugging Helper

The biggest thing I struggle with when building out extremely large forms with multiple steps is testing each individual input. Namely, that when I get to the end of the form to submit… I’ve almost forgotten what it was I typed at the start!

There’s actually a nice way to debug this (Atleast in Dev). The first thing we want to do is go to a parent component of our entire form, in our example project’s case, that’s simply the app-component. The first thing we do is inject the formDataService into the backend.

export class AppComponent {
  constructor(public formDataService : FormDataService) {
  }
}

Then we need to edit the HTML of the AppComponent to output the models of the service as JSON. That looks like so :

<h1>My Multistep Form</h1> 
<router-outlet></router-outlet>
Personal Details : {{this.formDataService.personalDetails | json}} <br />
Address Details : {{this.formDataService.addressDetails | json}}

Now as we fill out the form, on all steps we have a live update of how our model actually looks on the backend.

Not only is it handy when we get to the end of the form to be able to see what we “should” be submitting just before we submit it, but also if we have any complex controls/custom controls in our form, we can see exactly what’s going on in the backend as we fill them out.

Is This The Best Method?

Finally I just want to touch on if this is the “best” way of achieving a multi step wizard in Angular. You could probably swap out “best” for “most efficient”, “proper”, “up to date”, however you want to say it. As I said early on, this is the way I’ve been building these sorts of forms since the very early days of Angular. It’s served me well and even with things like Reactive Forms and RxJS becoming increasingly popular, I find this to be the most straight forward method. There’s no hidden “magic” or library doing things on the backend, it’s just simple code that works.

This article is part of a series on creating multi step form wizards in Angular.

Part 1 – Basic Setup
Part 2 – Building Our Forms
Part 3 – Tying It All Together


In the last part of this series on building a multi step form wizard, we got a simple project up and running, but it wasn’t really doing a heck of a lot. Let’s change that by building out the HTML forms to capture some basic information.

Personal Details Form Build

The first thing we want to do is to generate a new component called “PersonalDetails”. We can do that in the Angular CLI :

ng generate component PersonalDetails

The first thing we need to do is wire up the component to pull in the service, and load the personal details model out. Without too much faffing about, it will look like :

export class PersonalDetailsComponent implements OnInit {

  personalDetails : PersonalDetails;

  constructor(private formDataService : FormDataService) { 
    this.personalDetails = formDataService.personalDetails;
  }

  ngOnInit() {
  }

}

Pretty simple really. Inject the service in, pull out the personal details model, and set it locally. Remember that because the FormDataService is a singleton, for our entire app (per page load), there will only ever be one instance.

Next, we can replace personal-details.component.html with the following amazingly styled HTML.

<table>
    <tr>
        <td>First Name</td>
        <td><input type="text" [(ngModel)]="personalDetails.firstName" #firstName /></td>
    </tr>
    <tr>
        <td>Last Name</td>
        <td><input type="text" [(ngModel)]="personalDetails.lastName" #lastName /></td>
    </tr>
    <tr>
        <td>&nbsp;</td>
        <td><input type="button" value="Next" routerLink="addressdetails" /></td>
    </tr>
</table>

Not yes, we are using tables. And yes this is not going to look great at all but it’s just a demo!

Everything here should be rather straight forward. We have two text boxes, and they bind to the personal details object on the component. Then we have a next button that routes to our (future) address details component. This link obviously won’t work right now, and will actually break everything if you try and view it! Grrr!

What we need to do is first create the AddressDetails component by going

ng generate component AddressDetails

Then we need to open up our app-routing.module.ts file, at the top will be a const of routes that will (probably) be empty right now. Change it to the following :

const routes: Routes = [
  { path : '',   component : PersonalDetailsComponent }, 
  { path : 'addressdetails',   component : AddressDetailsComponent }, 
];

This then wires up our two components, the first will be on the homepage, and the next will be at /addressdetails.

Run a quick ng serve, and we should end up with something like :

It’s not pretty, but it works! Click Next will take us to our AddressDetails component which is actually empty. So let’s fix that!

Address Details Form Build

We’ve already generated our AddressDetails component so that we could route to it, so let’s just fill it out.

Our component definition should look like so :

export class AddressDetailsComponent implements OnInit {

  addressDetails : AddressDetails;

  constructor(private formDataService : FormDataService) { 
    this.addressDetails = formDataService.addressDetails;
  }

  ngOnInit() {
  }

}

And the actual HTML of the component should look like :

<table>
    <tr>
        <td>Full Address</td>
        <td><input type="text" [(ngModel)]="addressDetails.fullAddress" #fullAddress /></td>
    </tr>
    <tr>
        <td><input type="button" value="Back" routerLink="" /></td>
        <td><input type="button" value="Complete" /></td>
    </tr>
</table>

Now we could go ahead and deep dive this code but I think it’s pretty self explanatory. In our component we load out the FormDataService which is actually the exact same instance we used in the PersonalDetails component (Infact we could access the PersonalDetails model if required here), and then we display a simple form bound to the AddressDetails model.

Now the most important think to notice is that if we run our solution and test it. We can type in our personal details, press next, enter in our address details, but then press *Back*. Our Personal Details are re-loaded out of our shared service and pre-populated into the form! We haven’t had to do some crazy loading/unloading of models into our form, simple data binding does the magic for us.

In the next part of this series, we will look at how we then post our data to an API, and some tips and tricks working with larger multi step forms. Check it out here.