On almost every single Angular project after a certain size, you’ll start running into these errors :

An unhandled exception occurred: Call retries were exceeded

Or

JavaScript heap out of memory

Both of these point to the same issue. That your build process is hitting memory limits and simply crashing. It can be frustrating to debug for a few reasons.

  • Memory limits can be set for all NodeJS processes on a machine, meaning that what will build on one developers machine may not build on another because they may have already upped/lowered their memory limits.
  • Similar to the above, certain hosted build agents (e.g. Azure Devops, Github Actions etc), may have memory limits set lower/higher than you might think, meaning that builds succeed/fail here when they wouldn’t otherwise on other machines.
  • Non production builds of your angular project (e.g. Just using ng serve) build fine, but building with the production flag consumes far more memory, and so may crash only when building in production.

Luckily there is a really easy fix that gets around all of the above. While you can leave a note in the readme saying “Hey, you need to up your memory to XYZ”, a better option is to create a npm build script that sets the memory limit for that build only, and leaves everything else on the machine as is.

For example, a recent project of mine has these sets of scripts in the package.json :

"scripts": {
  "ng": "ng",
  "start": "ng serve",
  "build": "ng build",
  "test": "ng test",
  "lint": "ng lint",
  "e2e": "ng e2e",
  "build-prod": "node --max_old_space_size=8000 ./node_modules/@angular/cli/bin/ng build --prod",
}

Notice the last script. It looks complicated but it’s actually quite simple.

  • Start the Node process.
  • Set the “max old space size” to 8000MB.
  • Find the angular CLI in your node modules folder.
  • Run an angular build of production.

Now anytime we need to build for production, we only need to run “npm run build-prod”, including on our build servers.

As to what you should set your memory limit to. You should try and set it relatively high, but not enough to consume all of your memory on your machine. By default, depending on your installed version of node, the default is between 500MB to 1GB. So even allowing up to 2 or 4GB should be enough to build most Angular projects.

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.

Over the past couple of months I’ve been doing battle with an Angular Universal project. Angular Universal is Angular’s answer to Server Side Rendering or SSR for short. Why use SSR? In most cases it’s for SEO purposes but in some cases it also gives “perceived” performance.

For SEO, when opening a link to an SSR website, Angular renders the complete (Or semi-complete) page on the server, and returns the HTML that can be read by search engines (and other robots).

When I say “perceived” performance, what I mean is that because it’s atleast semi-rendered,  a user doesn’t see a flash of a blank screen like you normally get with regular Angular apps. I personally don’t think it really returns the complete page any faster than a regular Angular App, but the first paint is more “complete” than that of a regular Angular app.

It sounds good on the surface, but just try and have a quick search for how many people are actually using Angular Universal in production – there’s not many. Almost every tutorial you find on the subject is the Angular Universal equivalent of a “Hello World”. I won’t say I’m an expert on Angular Universal, but I wanted to write this article to maybe show you a couple of things that every tutorial leaves out of the conversation.

Library Support Is Rough

The first thing you probably learn when using Universal is that when the page is rendered on the server, it doesn’t have access to a couple of really important (common) javascript paradigms. Among them, you can’t access the window object (Since this refers to the browser window of which there isn’t one when doing server side rendering), you can’t access things like localStorage or any sort of memory that might live inside a browser window like Session Storage. Cookies are also a bit of an issue for obvious reasons.

Angular recommends you wrap things that need to access these objects inside a method called isPlatformBrowser so that you can check if you are in that moment doing server side rendering or if you are doing it in a browser. (More info here https://github.com/angular/universal/blob/master/docs/gotchas.md).

But, that’s with your code. What about something like an authentication library that uses localStorage? Like the MSAL library from Microsoft that allows your javascript application to integrate with Azure AD. They have a great Angular package that makes authentication a cinch. But they obviously haven’t gone and wrapped everything in browser checks. Why would they muddle their code with that when very very few people are using Angular Universal anyway?

And I ran into this same problem many times over. Even just libraries that try and access the window object (which has to be pretty common in javascript), they are going to completely bomb out when running inside Angular Universal. Of course, you can always fork the code or try and add in a bunch of browser checks yourself, but the point is is that all those libraries that were plug and play on your last project suddenly become a headache to get integrated.

Development Is Extremely Slow And Confusing

Let’s face it, building Angular Universal bundles are slow. When you have a plain Angular app and you run “ng serve”, it’s snappy. The watchers are fast and changing a couple of lines typically only takes a couple of seconds to recompile. I’ve found Angular Universal to be the exact opposite. Often with recompiles taking almost the exact same time as the initial compile. Those jokes back in the day of “can’t work, code recompiling” when you were working on mainframes are back!

I also found debugging of Angular Universal apps incredibly complicated and often confusing. You see it’s only the *initial* request that is server side rendered. As you click around the site, you are then inside a regular Angular app and therefore everything is client side. But common debugging tools like console.log() become very confusing to follow because if it’s an initial request, that log will be written on the server, not in the browser, all subsequent logs will be written to the browser. Same goes for any debugging tool you might use. The initial request would be like debugging a typical Express application, but all subsequent requests can be debugged just fine from the browser. Trying to bring a new developer up to speed is pretty damn difficult.

Documentation Is Terrible

Finally. The documentation is terrible. Angular Universal has one, yes one, page of documentation here : https://angular.io/guide/universal. That’s it. I even had to log a bug that the sample application they provide doesn’t actually compile at all. And they closed it was they were “working on it”. So not sure how hard it is to just provide a working example of an Angular Universal app, but evidently it’s still not been updated.

Beyond the official documentation, you typically rely on other examples and blogs floating around on the web that really only scratch the surface of what Angular Universal does. If you run into any roadblocks at all, you are pretty much on your own because as far as I’ve seen, no one actually uses Angular Universal in any large commercial capacity (Happy to be proven wrong though!).

Should You Use Angular Universal?

I’m a big believer in using the right tech for the right purpose. As it stands right now, I believe that if you need server side rendering, then don’t use a client side javascript framework to do it. While it’s not too hard to turn any app into Angular Universal. On any project of reasonable size, you’ll start hitting roadblocks thick and fast and soon realize that Angular Universal is a fun POC, but not a commercial offering.