I was recently banging my head against the wall for a very annoying error that only occurred on my build server, but not locally. The error in question was when a component referenced an external style sheet, I was getting the following error :

Couldn’t Resolve Resource ./foo.css Relative To foo.component.ts

I’m going to go through a tonne of solutions here, any one of them could be your solution so don’t dismiss any of them until you’ve given it a go. The basis for this error is that whatever build tool you are using (Gulp or Webpack), can’t find your style file. In some rare cases, this also applies to your component not being able to find your template html, and all of the following solutions still apply.

You Are Using Inline Styles

If you are building templates using inline styles, then often it can be a bit of a copy paste error when you end up with something like so :

@Component({
    selector : 'app-header',
    templateUrl : './header.component.html',
    styleUrls : ['h1 { float:left }']
})

And this may look very obvious but it’s happened to me before! If you are looking to use inline styles, you should change that styleUrls to be styles like so :

@Component({
    selector : 'app-header',
    templateUrl : './header.component.html',
    styles : ['h1 { float:left }']
})

You Are Not Using Any Styling At All

The next solution is actually similar to the previous. Imagine that you don’t want to be using any styling at all, so you simply delete the style file and blank out the URL like so :

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

This will still in some cases (Depending on your build pipeline) blow up. If you are intending to not use any styles at all, just completely remove the styleUrls all together like so :

@Component({
    selector : 'app-header',
    templateUrl : './header.component.html'
})

Relative vs Absolute Paths

I mostly see this in projects that move from things like Gulp to Webpack or vice versa. Even more so again when people are copy and pasting code from other projects. In some cases, Gulp for example likes absolute paths like so from the very root of your project.

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

Whereas WebPack prefers relative paths from where the component.ts file is located. So if the css file is in the same folder we can change everything to be relative :

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

However, again, this is totally dependant on what build tool you are using. The majority of projects will be using Webpack and therefore require relative paths, but just incase, and if you aren’t sure, try the absolute URL style yourself just to rule it out.

Case Sensitivity

This one has caught me out plenty of times as a Windows developer who typically has build agents running Linux. Windows is case-insensitive for file paths. Therefore this will build completely fine on a Windows machine :

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

However it will blow up when building on a Linux machine. The solution is obviously pretty simple, either rename the styleUrls to the correct casing *or* rename the file in Source Control (Which in of itself can be difficult on Windows). Either way, don’t discredit a small casing issue completely blowing things up.

The concept of Attributes vs Properties in Angular can get confusing at times. Mostly because often there attributes and properties with the exact same name. If we take a simply example, using an input html tag such as :

<input type="text" id="nameInput" value="Jim">

Here we have an input HTML tag that sets a value of “Jim”. This sets the initial value of this input to “Jim”. If a user edits this value and changes it to “Jane”, we can observe two things :

  • If we use getAttribute(‘value’) on this input, it will return our initial value of “Jim” not “Jane”.
  • If we fetched the DOM property value for this input, it would be our new value of “Jane” not Jim.

This simplifies things for us a little because we can then boil down attributes vs properties in Angular to the broad concept of :

  • Attribute – Represents the initial value and does not change.
  • Property – Represents the current value and can change.

In Angular, we can go further to describe attributes as belonging to HTML. However once a page is rendered (broadly speaking), an attribute does not change and is purely used in the initial rendering process. Whereas a property is almost a “binding” to the current value, including the initial value set by an attribute.

Things can get a little complex in our heads when trying to understand whether we should use a property or attribute. But for the most part, we will be using properties. That’s because many HTML Attributes have a 1 to 1 mapping with DOM properties. Therefore getting/setting a property on an HTML element will generally speaking be fine.

There are however exceptions to this rule. Notable elements that have attributes, that do not have properties. A good example of this is the colspan attribute of a table cell like so :

<td [colspan]="4"></td>

We are passing in a hardcoded value of 4 here, but we may also pass through something like a property of our component :

<td [colspan]="columnCount"></td>

Either way, we would receive the following error :

Can't bind to 'colspan' since it isn't a known property of 'td'.

This is because colspan only exists as an attribute (And it’s important to note that in the error message, specifically it is talking about a known property). You would even get this message if you were just using string interpolation like so :

<td colspan="{{columnCount}}"></td>

However Angular gives us a way to set an attribute value, and avoid using properties. That is like so :

<td [attr.colspan]="columnCount"></td>

This sets only the attribute, and not the property. What this does tell us though is that colspan is not “designed” to be changed after the initial render (Of course, in modern times there are always exceptions to this rule).

Other common examples of attributes that don’t have corresponding properties would be all aria-* tags.

What about the other way around? Do properties exist that don’t have corresponding attributes? Of course! Plenty. Really any custom property you add to a component is a property that exists in the DOM but does not exist in HTML attributes!

Hopefully this goes some way to explaining why we have attributes and properties, and what their subtle differences in Angular are.

As part of a recent build of mine, I added the website to Google Webmaster Tools. Now, among other things, these tools provide insight into how Google sees your website functioning, and also gives feedback on any issues it found while crawling your pages.

A big focus for Google in the past 10 years, has been how websites function on mobile. Do they load in a reasonable time? Does the javascript require a huge amount of resources that makes your phone too hot to handle? And more recently, does your website function in a way that’s easy to use on a mobile touch screen?

That last point is frankly, a little subjective, but it’s one that Google is taking a keen eye on. And when you fail their test, you get a rather vague message of “Clickable elements too close together”. I actually searched the web for any tool that could actually pinpoint what exactly on my website was causing the issue, but to no avail. So unfortunately, there is a bit of trial and error involved. But you can speed up that trial and error by knowing where to look.

Element Size And Margin – The Key Culprits

Almost universally, you’re going to run into this problem when a clickable element is either too small, or it’s too close to another element that is also clickable. An example I will show you shortly was that I had a button that opened the side menu right up against a link that takes you back to the homepage. The button itself was too small, but additionally, the fact that there was no gap between the two items was also a mobile usability problem.

I hunted around for the exact numbers that I should be aiming for, and there seemed to be a little bit of a consensus on the following :

  • Any element that is clickable (That is not a text link) should be at least 48x48px (e.g. Buttons, images, SVGs etc)
  • Any element that is clickable should have at least 8px margin on all sides from any other clickable element

These are your starting points, so if you can look at your website right now and immediately identify problems with the above, then you are good to go! Start making changes and testing those updates using the steps below.

Finding Clickable Elements

One way to help you diagnose any mobile element problem is to add an outline to any element that is clickable. For that, you can use the following CSS :

a, input, button, svg {
    outline: 1px solid red;
}

Note that I’ve put SVG in there for my own needs (Since I have clickable SVG’s on my site), but should you not, then you can remove it. By the same token, if you have clickable elements that you want to check if they overlap, then be sure to add them.

You can either add this CSS in development *or* you can use something like Chrome Dev Tools to see things on the fly.

In my particular case, I ended up with a view like this :

Clearly now I can see that these elements are too close together and are actually overlapping somewhat. Using this visual tool, we can easily identify elements that don’t have the appropriate margin, and easily rectify them.

Every Element Is Tested

Something that caught me out is that elements I thought would be “invisible” to Google were in fact causing problems. This included a slide out menu that is only shown on mobile, and an iframe to another site. I figured that in the iframe’s case, I would not be penalised since I didn’t even think Google would bother loading the iframe in any testing tool. I was wrong, very very wrong!

This may be obvious, but just in case it isn’t, don’t assume something is not relevant to what Google is testing. If it’s on the page, or it’s reachable in some way, it could be causing the error.

Testing Changes

The easiest way to test if your changes have fixed the problem is to go to Google’s official tool at : https://search.google.com/test/mobile-friendly. I’ll be the first to admit that this tool can be a bit finicky and it sometimes takes a few changes to finally get your website the green light. Elements that I thought would be causing issues, actually were fine, and it was other inconspicious items that were doing all the damage. The trick is, just keep adding margins and testing your changes until you get it right.

If you are having to make large scale UI changes that you aren’t happy with, you still want to get to the point where Google is liking your page, and then you can start rolling back changes one by one, to see which changes actually had an affect. Again, it’s painful because Google will not tell you exactly which elements are causing problems, so trial and error is really your only way.

Some code I was working on required me to delve into what the differences between Empty, Never and Of were in RxJS. Specifically, I had a method that returned an observable purely so that I could “wait” or “subscribe” for it to finish (e.g. It did not return an actual result). Imagine something like this :

myMethod() : Observable<object> {
  //Go and do something
  return this.http.post('/myurl', null);
}

In reality, I’m not interested in the result, but I am interested in waiting until the call is complete. Therefore, I may have code such as :

this.myMethod().subscribe(x => {
  //Continue something here. 
})

Where I ran into issues, was what if I wanted to short circuit myMethod()? What if I had a cache or sorts, or logic that determined I didn’t need to call the API at all? What should I return to still fire my continuation method? The results were interesting..

Using EMPTY

RxJS 6+ has a special type called “EMPTY” that acts as an empty observable. When I first used this, my code compiled fine but while testing, I noticed that my continuation never fired.

The documentation for EMPTY (And it’s deprecated sibling empty()) state :

Creates an Observable that emits no items to the Observer and immediately emits a complete notification.

It’s important here to note that while the observer is completed, it emits nothing on it’s way to doing so. For example :

EMPTY.subscribe(x => {
  console.log('Empty Emit'); //This never fires. 
}, 
null, 
() => {
  console.log('Empty Complete'); //This does. 
});

What this means is that if you are using EMPTY to short circuit your code, but your code subscribes to the returned observable, EMPTY will in fact not work.

Using NEVER

While, given the name, I didn’t have high hopes that using NEVER would solve my problem, I did want to see how it functions. So using this code :

NEVER.subscribe(x => {
  console.log('Never Emit'); //This never fires. 
}, 
null, 
() => {
  console.log('Never Complete'); //This never fires. 
});

NEVER well… It never fires anything. It doesn’t emit anything nor does it complete the observable. This may be useful in very limited cases where you need to return a value, but you don’t want subscribers to act on it *or* for anyone to act on the observable completion.

Using Of

That brought me to using Of. I had used this before but slowly drifted to using EMPTY when in fact, using our example :

of({}).subscribe(x => {
  console.log('Of Emit'); //This fires. 
}, 
null, 
() => {
  console.log('Of Complete'); //This fires. 
});

This works perfect! Not only does the emit fire, but the observable also completes. I would like to point out that in this example, I have used of({}), if you instead use Of() with no value, then you will instead complete the observable but not emit a value (Similar to EMPTY). Of simply wraps a static value in an observable and emits immediately, allowing you to short-circuit otherwise asynchronous methods.

Which One To Use?

If you want to return a value and call all subscribers, then you must use Of(value).  If you want to return a value and *not* call subscribers, then use EMPTY. If you subscribers not only act on emit, but also on completion and you want to avoid this behaviour, use NEVER.

I’ve been developing in Angular for many years now, and something that either passed me by, or I just never ran into a problem with it, is that if a route has multiple route guards, they will all run at once asynchronously. Obviously the result of all of these are waited on, and the route will not navigate unless the guards succeed, but the guards themselves all fire at once. In some scenarios this is desirable for speed, but in others… a little less so.

I had a scenario where I had two route guards. The first was simply to check if the user was logged in via an OAuth process. The second guard was to check if the user had a particular role, but it essentially depended on the first route guard checking the login status. I assumed (wrongly), that this set up would work as the first guard checks if the user is logged in, *then* we check the role they have in the second guard. Instead, I ran into multiple issues where the second guard would fire before the first, breaking my entire application.

The solution is that we need a “Combined” guard to run a given set of guards one after the other, synchronously. I made one like so :

@Injectable({
  providedIn: 'root',
})
export class CombinedGuard implements CanActivate {
  constructor(private injector: Injector) {
  }

  async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise {
    const guards = route.data.guards || [];
    for (const guard of guards) {
        const instance: CanActivate = this.injector.get(guard);
        let result  = instance.canActivate(route, state);

        //Depending on the route result, we may need to await upon it in different ways.
        if(result instanceof Promise) {
            result = await result;
        }

        if(result instanceof Observable) {
            result = await result.toPromise();
        }

        if (result === false || result instanceof UrlTree) {
            return result;
        }
    }
    return true;
  }
}

To use this, we need to use the data property of a route to set the guards rather than the guard property :

{
  path: 'admin',
  canActivate: [CombinedGuard],
  data: {
    guards : [LoginCheckGuard, AdminRoleGuard],
  }
}

Notice how we pass our two guards (LoginCheckGuard and AdminRoleGuard) as data properties, not inside the canActivate, and instead pass the CombinedGuard as the actual canActivate guard.

Surprisingly, I found many people with the same issue complaining on the Angular GIT repository, but as of yet, no official fixes. It does seem slightly strange to me as running guards in a particular order does seem like a common use case, but for now, you’ll have to use the CombinedGuard.

Coming from a C# background, I don’t tend to use Discriminated Unions a whole awful lot. By Discriminated Unions, I mean having a method that may take multiple different types, or may return multiple different types.

If you’ve come from a C# world, it’s basically like method overloads when passing parameters into a method. And the other way, it allows you to make a method that could return one of many different types, that don’t necessarily have to have an inheritance relationship between them.

Let’s see how this might work :

class Plane {
}

class Car {
}

getVehicle() : Plane | Car {
    //Either of these are valid. 
    return new Plane();
    //return new Car();
}

It’s somewhat strange at first to get used to this ability if you’ve never used a language that uses unions. Most developers would instead make a “base” class of “Vehicle” and make both Plane and Car inherit from Vehicle, and then you don’t need a union. Which.. In my view is probably valid.

But lets say you can’t do that, and you are dealing with code that either returns a Plane or Car, *or* code that accepts a Plane or Car. You’re going to need to know at some point, which one you have. Because if the objects were identical, you probably wouldn’t need this union at all. Type checking in Typescript on the surface seemed easy, but I went down a bit of a rabbit hole through documentation and guides that weren’t always clear. So I want to try and simplify it down all right here, right now.

Using The TypeOf Operator

Javascript actually has a typeof operator itself that can tell you which type a variable is. As an example, we can do things like :

let variable1 = 'abc';
let variable2 = 123;
console.log(typeof variable1);//Prints "string"
console.log(typeof variable2);//Prints "number"

But.. This isn’t as helpful as you might think. Other than the fact that it returns the “type” as a string, which is rather unhelpful in of itself, it doesn’t work with complex types. For example :

let myCar = new Car();
console.log(typeof myCar);//Prints "object"

For all custom classes (Which, in modern JavaScript you will have many), the return type is only ever object. That’s because the typeof operator can only tell you which primitive type your variable is, but nothing beyond that.

For this reason, while it may be helpful for telling strings from numbers, anything more, typeof is out!

Using The InstanceOf Operator

That brings us to the instanceof operator. It’s actually rather simple! We can just change our code to work like so :

let myCar = new Car();
console.log(myCar instanceof Car);//Prints true

Works well and we can now tell if our variable is an instance of a car. But there is a caveat, and it’s around inheritance. Consider the following code :

class Car {
}

class Honda extends Car {
}

let myCar = new Honda();
console.log(myCar instanceof Car);//Prints true

Notice that even though our variable holds a “Honda”, it still returns true as a car. For the most part, this is how all programming languages work so we shouldn’t read too much into this “limitation” as it’s really just polymorphism at play, but it’s still something to keep in mind.

Alas, we have an issue! A really smart developer has come along and said that interfaces are the new hip thing, and we should switch all classes to interfaces in our front end code. So we have this :

interface Car {
}

let myCar = {} as Car;
console.log(myCar instanceof Car);//Error 'Car' only refers to a type, but is being used as a value here.

This time around, we don’t even get to run our code and instead we get :

'Car' only refers to a type, but is being used as a value here.

What’s going on here? Well.. the instanceof operator works with classes only, not interfaces. Gah! OK but actually there is a way to check this further!

Using The As Cast Operator

Consider the following code (And yes I know it’s a fairly verbose example, but should hopefully make sense!)

interface Car {
  carMake : string;
}

let myCar = {carMake : 'Honda'};

let processCar = (car : object) => {
  //Some other code. 
  if(car as Car){
    console.log((car as Car).carMake);
  }
}

processCar(myCar);

Notice how we can cast our variable to a Car, and check if it has a value (by using a truthy statement, it will be undefined otherwise). Casting is actually a great way to determine whether variables are instances of an interface.

Using Typescript Type Guards

One thing I want to point out about the above code is that we have had to actually cast the car twice. Notice that inside the console log, we had to cast again for intellisense to pick up we were using a Car.

console.log((car as Car).carMake);

Typescript has a way to deal with this however. It’s called “Type Guards”, and it allows you to write code that will not only check an object is a given type, but that Typescript from that point on can treat the variable as the type.

For example, we can create a custom type guard like so :

function isCar(car : any): car is Car{
  return (car as Car) !== undefined;
}

The magic sauce here is the return type. It’s actually “car is Car”. That tells Typescript that should this return true, the input variable can be treated as a Car from this point onwards. This allows us to change our code to instead be :

let myCar = {carMake : 'Honda'};

let processCar = (car : object) => {
  //Some other code. 
  if(isCar(car)){
    console.log(car.carMake);
  }
}

processCar(myCar);

Notice how inside our console log, we didn’t have to cast again to have it act as a car.

This is a really important concept when talking about type guards. It’s not just a way to create a nice fancy method that can be used to check types, it actually allows Typescript to start treating what could be an unknown object type, as a very specific one within that code block.

Sometimes Angular can be a real headache when it comes to some really basic use cases, especially when form building.

Case and point, I recently had to get all controls within a ngForm so that I could run a custom method on them. At first, I figured that something like so would suffice :

let myControls = myNgForm.form.controls; //<-- This should get all controls right?

But actually this only returns the name of the inner controls, but not the control object itself. Luckily, there is a simple way to then get the control based on the name using a for loop :

for(const field in myNgForm.form.controls) {
    const control = myNgForm.form.get(field); //This gets the actual formControl. 
}

This works perfectly and our control variable is now set to the actual AbstractControl object (Which we can then cast to a FormControl/Group/Form etc if we need to).

There’s one more step we need to do though. The problem with this is that I don’t want to have to copy and paste all of this around my code base. So let’s make it reusable!

The first thing we need to do is create a file called ng-form.extensions.ts, hopefully in an extensions folder, somewhere in our project. Inside of it, we want the following :

import {  AbstractControl, NgForm } from '@angular/forms';

declare module "@angular/forms/" {
    interface NgForm {
      getAllControls(this:Form) : AbstractControl[];
    }
}
NgForm.prototype.getAllControls = function(this:NgForm) {
    let controls : AbstractControl[] = [];
    for(const field in this.form.controls) {
        const control = this.form.get(field);
        controls.push(control);
    }
    return controls;
}

If you haven’t seen this type of code before, it’s how we can add “extension” methods to existing interfaces from Angular. What we are doing here is essentially telling Typescript that NgForm actually has another method called “getAllControls” available to it, that returns an array of AbstractControl.

Anywhere we want to use this, we can simply add an import to the top of whatever file :

import 'src/app/_core/extensions/ng-form.extensions'; //Obviously this is the actual location of your extensions file

And then use it like any other method in your component :

this.myForm.getAllControls();

Nice and easy! And super re-usable. The best thing is that you can add more and more extensions to your NgForm any time you feel there is something missing from the default behaviour, and you don’t need to create all sorts of complex services that take an NgForm parameter, you can add it directly onto the interface itself!

A very common question I field from developers new to Angular is what does the “static” property do when using ViewChild. For example, if we have code like so :

@ViewChild(ChildComponent, {static : false}) 
childComponent : ChildComponent;

What exactly does setting static to false do?

I think the documentation is actually rather light and I’ve seen lots of posts around the subject that explain the end behaviour of setting static to true or false, but not what it’s actually doing. A bit like describing the symptoms rather than what’s actually going on.

So let’s break it down!

What Does Static Actually Do

Static stands for whether the ViewChild is “static” content e.g. Always available on the page, no matter page bindings, API calls, ngIfs etc. When set to true, we are telling Angular that the ViewChild will be available at anytime, so simply query for the ChildComponent at the earliest lifecycle hook available and then never query again.

However, if we set static to false, we are saying that the ViewChild will be available at a later time, but it’s dependant on a condition (Such as an API call, or a simple component property binding), and therefore we must check for the ViewChild every time ChangeDetection runs. Understandably, this can create a higher performance load because we must always be checking if our ChildComponent is available any time the component changes.

Access In Component Lifecycle Hooks

I want to talk a little bit about how the setting of the static property affects how early we can access the ViewChild. This is one of those symptoms I talked about earlier. Setting static to true or false does affect which lifecycle hook you can access the ViewChild, but it’s more a side effect of what static is actually doing rather than the intention of the property.

When static is set to false, it is only available during the ngAfterViewInit lifecycle hook at the very earliest because this is the very first lifecycle hook that runs after ChangeDetection for the component.

In code form, if we have a component like so :

export class AppComponent implements OnInit, AfterViewInit {
  @ViewChild(ChildComponent, {static : false}) childComponent : ChildComponent; //Notice the static false

  ngOnInit(): void {
    console.log(this.childComponent);
  }

  ngAfterViewInit(): void {
    console.log(this.childComponent);
  }
}

Notice that static is set to false. And therefore, our ViewChild is not available in ngOnInit. If we run the code, we get this :

undefined
ChildComponent

Changing the code to instead use static true

export class AppComponent implements OnInit, AfterViewInit {
  @ViewChild(ChildComponent, {static : true}) childComponent : ChildComponent; //Notice the static false

  ngOnInit(): void {
    console.log(this.childComponent);
  }

  ngAfterViewInit(): void {
    console.log(this.childComponent);
  }
}

Instead now when we run our code, our ViewChild is available earlier.

ChildComponent
ChildComponent

So Should We Always Use Static True Then?

So the question then becomes, if we can get access to our ViewChild earlier, why not just always make it available as soon as possible? There’s actually one big reason, but I’ll give two examples to show how always setting static to true on ViewChild can cause a few headaches.

In this first example, I’m going to add a boolean to our code on whether we should show our ChildComponent or not. The code behind looks like so :

export class AppComponent implements OnInit, AfterViewInit {
  shouldShow = true; //This is our new boolean. 
  @ViewChild(ChildComponent, {static : true}) childComponent : ChildComponent;

  ngOnInit(): void {
    console.log(this.childComponent);
  }

  ngAfterViewInit(): void {
    console.log(this.childComponent);
  }
}

With HTML utilizing a simple ngIf :

<app-child *ngIf="shouldShow"></app-child>

When static is set to true, our output is :

undefined
undefined

So not only is ViewChild not available during ngOnInit, it’s actually never available. And the reason is that when we set static to true, Angular only tries to find our ViewChild *once*, and only once. If our ViewChild is not available in the DOM when Angular checks, it is never queries for again. Even in this case where shouldShow is a constant value, ChangeDetection does not run until later in the component lifecycle – after Angular tries to fetch a ViewChild initially.

However if we change static to false, then instead we get this :

undefined
ChildComponent

Because ngAfterViewInit runs after the first ChangeDetection cycle, our component is available, and because setting static to false means after every ChangeDetection, we re-query, we are able to find our ChildComponent.

How about a second example? Let’s take this code :

export class AppComponent implements OnInit, AfterViewInit {
  shouldShow = false; //This is our new boolean. 
  @ViewChild(ChildComponent, {static : false}) childComponent : ChildComponent;

  ngOnInit(): void {
    console.log(this.childComponent);
    timer(2500).subscribe(x => 
      {
        this.shouldShow = true;
      });

    timer(3000).subscribe(x => 
      {
        console.log(this.childComponent);
      })
  }

  ngAfterViewInit(): void {
    console.log(this.childComponent);
  }
}

I want to use this example because it shows it’s not about Lifecycle Hooks at all. It’s just that some people boil it down to something like :

  • Static = true. Access in ngOnInit
  • Static = false. Access in ngAfterViewInit

And the reality is it’s actually got nothing to do with that. It’s about ChangeDetection. In our above example, both the logs from ngOnInit *and* ngAfterViewInit will be false, however when our timer goes off, and we set shouldShow to true, and then 500ms later we check the ChildComponent, it will be available.

Which One To Use?

The rules for which one to use is actually quite simple.

  • If your ChildComponent is hidden or dynamically loaded in some way via component binding (Either with property binding or an API call), then you *must* set static to false.
  • If your ChildComponent is always available on the page, and is never hidden. Then you can use *either* static false or static true. But setting static to true is more performant, and gives you earlier access to the component (if required).

This article is part of a series on Inter-Component Communication in Angular. While you can start anywhere, it’s always best to start at the beginning right!

Part 1 – Input Binding
Part 2 – Output Binding
Part 3 – Joining Service
Part 4 – ViewChild


We’re now onto our final method of communicating between components in Angular. And this is one that I wasn’t sure if I should really write up. You see, using ViewChild to get components talking to each other, in my opinion, is the last resort. It isn’t that reactive and often runs into various race conditions because you aren’t using things like EventEmitters and data binding, and instead you are resorting to call methods directly.

For the above reasons, I’m going to make this short and sweet because for the most part, you won’t be using ViewChild to communicate between components, but it’s still good to know it’s an option.

Calling A Method Via ViewChild

Imagine I have my AppComponent like so :

import { Component, ViewChild } from '@angular/core';
import { ChildComponent } from './child/child.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  @ViewChild(ChildComponent, {static : false}) childComponent : ChildComponent;

  runChild() {
    this.childComponent.run();
  }
}

That also has HTML like so :

<button (click)="runChild()">Click Me</button>
<app-child></app-child>

We now have an AppComponent, with a button that when clicked, will “run” our child component.

Also notice that we use the @ViewChild() directive to find the ChildComponent in our HTML. There are a few different ways to do this, for example you can use the #name format in your HTML and then use that name to find the child, but the important thing here is that we can use @ViewChild() to essentially find child elements within the html and get a reference to them.

Our ChildComponent looks like so :

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  run() {
    //Maybe a bunch of logic here. And then we set a message. 
    console.log("Run Successfully!" );
  }
}

Nothing too fancy. Upon running this solution, when we click the button in our AppComponent, it calls the run method of our ChildComponent, and everything is great! So, the first thing to get into is..

Where Should You Use ViewChild

ViewChild in my opinion has a very discrete use case. When you need to call a specific method within a child component *and* you would like to subscribe to it (Or await a promise from it). It can allow you to do sync calls to a child component, and actually wait till it’s done before being completed.

Where you shouldn’t use ViewChild is :

This article is part of a series on Inter-Component Communication in Angular. While you can start anywhere, it’s always best to start at the beginning right!

Part 1 – Input Binding
Part 2 – Output Binding
Part 3 – Joining Service
Part 4 – ViewChild


In our two previous posts in using Input Binding, and then Output Binding for intercomponent communication, one thing is common between the two – there needs to be a direct parent/child relationship between the two components that need to talk to each other. While this is often the case, with a parent component passing down values to a child component, it’s also pretty common that components need to talk to each other either as siblings, or even distant cousins! For that, the best thing to use, hands down, is a “joining service”.

A good example of this is our guide to building a multi step wizard in angular. There, we used a joining service to hold the values of the individual form steps, and then at the end bring them all together. While this may not seem like “inter-component communication” at first, when you think about how each step of the wizard needs to pass on it’s values to the next step, then it totally makes sense!

Value Sharing via Joining Service

The first example I want to show is how we can share values between services. It’s actually pretty simple. Let’s create a service called “MyJoiningService” :

@Injectable({
  providedIn: 'root'
})
export class MyJoiningService {

  constructor() { }

  public myValue : string;
}

Nothing too fancy, we are just exposing a string value. Importantly, we have added the providedIn: “root” declaration. This means (In simple terms), that there will only ever be one instance of this service available, no matter which component uses it. So if we do this in our FirstComponent :

export class FirstComponent implements OnInit {

  constructor(private myJoiningService : MyJoiningService) { }

  ngOnInit() {
    this.myJoiningService.myValue = "ABC";
  }

}

And then in our second component we do :

export class SecondComponent implements OnInit {

  constructor(private myJoiningService : MyJoiningService) { }

  ngOnInit() {
    let someValue = this.myJoiningService.myValue; //The value is ABC
  }

}

The myValue property inside JoiningService is now shared between two components, even if the two components aren’t related to each other directly in HTML.

It’s really not rocket science and when spelled out like this, it probably seems a little too easy. Really the providedIn declaration is doing the magic for us, being able to share the exact same instance/singleton within our application.

Now this example works, but only if these two components aren’t on the same page. Otherwise we have a little bit of a race condition in that our SecondComponent needs to read the value *after* it has been set by the FirstComponent. But what if the value is set by a user interaction? How can we “alert” the SecondComponent the value has changed, by way of our joining service?

Using Subjects via Joining Service

To solve our problem of being “notified” when a new value is passed into our Joining Service, we are going to use Subjects. So let’s modify our service to look like so :

export class MyJoiningService {

  constructor() { }

  private myValue = new ReplaySubject<string>(1);

  public addMyValue = (value : string): void => this.myValue.next(value);

  public onMyValue = this.myValue.asObservable();
}

We have made “myValue” now be a Subject (Although in this example, we are using ReplaySubject, for why that is, check out our article on Subject vs ReplaySubject here : http://tutorialsforangular.com/2020/12/12/subject-vs-replaysubject-vs-behaviorsubject/).

We then have two additional properties. The first is an “addMyValue” method, that adds a value into the subject. And the second is an “onMyValue” property which acts as an observable for components to subscribe to changes.

We can then modify our FirstComponent like so to pump a value into the joining service :

export class FirstComponent implements OnInit {

  constructor(private myJoiningService : MyJoiningService) { }

  ngOnInit() {
    this.myJoiningService.addMyValue("ABC");
  }
}

And our SecondComponent can then listen for the value like so :

export class SecondComponent implements OnInit {

  someValue : string;
  constructor(private myJoiningService : MyJoiningService) { }

  ngOnInit() {
    this.myJoiningService.onMyValue.subscribe(x => {
      this.someValue = x;
    })
  }

}

Note that the use of the ReplaySubject is nice here because it doesn’t matter when the SecondComponent starts listening – we’ve managed to remove our race condition! Even if it “subscribes” late, because we use a ReplaySubject, it will still give us the last value that was passed into the JoiningService.

I use this pattern a tonne when trying to sync up components that have no direct relationship to one another. For example, a recent application of mine was built to receive inbound calls via Twilio in the browser, however when an inbound call was received, we wanted to disable some functionality of a couple of components so that you didn’t get direct messages while on your inbound call. We did this by creating a call service that would be able to alert other components when a call was in progress, without the need for direct component to component communication.

The other obvious benefit of using this is that it decouples components from one another. In our example, FirstComponent doesn’t know about SecondComponent, and vice versa. FirstComponent just knows that it can push values into the joining service for any number of other components to listen to, without needing to know who is subscribing to the observable.

Next

In the final part of our series, we are going to look at how we can use ViewChild in very select scenarios where we have a direct component relationship, but need to do more than just pass values around. It’s a rare usecase, but I do end up using it once or twice in each project when I’m in a jam. Check it out here : Inter-Component Communication In Angular – ViewChild