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 : https://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

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 previous post, we talked about inter-component communication using the Input declaration, to pass values into a child component. Now, it only makes sense that we talk about using the Output keyword, to pass values from a child component to it’s parent. To me, the Output declaration is easier and more straight forward than Input, but let’s get started and see what you think!

Basic Output Usage

At it’s simplest, we can mark an EventEmitter using the @Output() declaration on a child component like so :

export class ChildComponent {
  @Output() message : EventEmitter<string> = new EventEmitter<string>();

  sendMessage() {
    this.message.next("Hello World!");
  }
}

Then when we place this component on any page, we can modify it’s tag to listen for the message event :

<app-child (message)="onMessage($event)"></app-child>

Where “onMessage” is a method on the parent component that should be run when the value is passed back, and $event is the value of the message.

Very easy!

One thing that strangely I find people don’t realize initially, is that your event does not actually need to hold a value. For example, if you want to raise an event from your component when a click event happens, I often see people do something like this :

export class ChildComponent {
  @Output() click : EventEmitter<boolean> = new EventEmitter<boolean>();

  sendClick() {
    this.click.next(true);
  }
}

Notice the boolean and returning true? I don’t know why, but I’ve come across this in many projects, sometimes even with number values where they just return “0”. Little do they know, that EventEmitter is quite happy with a void type like so :

export class ChildComponent {
  @Output() click : EventEmitter<void> = new EventEmitter<void>();

  sendClick() {
    this.click.next();
  }
}

And that’s honestly all there is to the output keyword. Create an EventEmitter, add the @Output() declaration, listen to it in the parent. Done!

Two-Way Binding

Next we want to talk about two way binding. Two way binding is actually nothing more than syntax sugar for taking values emitted, and automatically setting them a variable. Let me demonstrate with an example.

Imagine I have a child component that looks like so :

export class ChildComponent {
  @Output() messageOut : EventEmitter<string> = new EventEmitter<string>();
  @Input() message : string;

  changeMessage() {
    this.messageOut.next("Hello World!");
  }
}

Here we can take a message in using the @Input() message line. We can also output a message through the messageOut EventEmitter. All seems pretty normal.

Next, we head to our parent component, and add the control like so :

<app-child [message]="myMessage" (messageOut)="onMessageOut($event)"></app-child>

And the code behind of our parent component :

export class ParentComponent {
  myMessage : string = "ABC";

  onMessageOut(message : string) {
    this.myMessage = message;
  }
}

So really all we are doing when we receive a new message out, is setting our variable of “myMessage” to that value. It’s a pretty common use case. And because of that, Angular has come up with a convention to do all of this for you. It works like this.

First we go to our child component, and make sure that the Output variable is called the same as the input variable, with the suffix of change :

export class ChildComponent {
  @Output() messageChange : EventEmitter<string> = new EventEmitter<string>();
  @Input() message : string;

  changeMessage() {
    this.messageChange.next("Hello World!");
  }
}

Then we head to our child component, and we can essentially wrap the binding with both the [] and () :

<app-child [(message)]="myMessage"></app-child>

Inside our actual Parent code behind, we can remove all event handling :

export class ParentComponent {
  myMessage : string = "ABC";
}

And this now works just the same! Angular uses the convention of an output variable named the same as an input, but with the suffix of “change” to mean that when next is called on the EventEmitter, you want the value to be set on the bound variable.

It’s actually fairly simple once you know it, but I’ve seen some really roundabout ways to achieve the same thing. Generally people actually ask things like “How do I name the output variable the same as the input” or “How do I combine input and output into one variable like ngModel?”. And what they actually mean is how do I two way bind in Angular!

Two Way Binding While Keeping Events

I just want to make a quick note on the work above. Commonly people tell me they don’t want to use two way binding because they still need an event to know when the value changes. Two way binding does not hide the event at all.

In our example above, we can actually still use the following :

<app-child [(message)]="myMessage" (messageChange)="onMessageChange($event)"></app-child>

So we get two way binding on the myMessage variable, but we can still listen for the event too! The order of events is that myMessage will be set by Angular before the messageChange event is run. I wouldn’t rely on this, but it’s the way it works right now.

You can even see this in action with ngModel like so :

<input type="text" [(ngModel)]="myMessage" (ngModelChange)="onMessageChange($event)">

New Angular developers tend to think that ngModelChange is some magic event that the Angular team are exposing so you can hook into the ngModel EventEmitter. But actually, it’s just a byproduct of ngModel being a two way bind (Notice that ngModelChange is just ngModel with the change suffix)!

Next

Next we’re going to take a walk through using a “joining service”. A joining service is required when your components may not have a direct relationship between each other (e.g. They are not parent/child). But we can still pass values between components using a service to facilitate the communication! Check it out here : https://tutorialsforangular.com/2021/05/01/inter-component-communication-in-angular-joining-service/

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


Inter-Component communication refers to the way that we can get components talking to each other. Sounds simple?! And for simple scenarios where there is a direct child to parent relationship, it is! But when components are not directly placed within one another, or they need to do more than just pass a variable back and forth, things can actually get complicated fast.

Rather than start at the complicated scenarios, we are still going to cover off the basics such as Input binding as for the most part, this is going to be your bread and butter. Then later on, we can start getting into more complicated scenarios such as using a joining service, or using the ViewChild declaration!

The first way we are going to get our components talking to each other is using one-way binding with the “Input” keyword. This is going to be by far the most common method of passing values into a child component, and it’s also one of the easiest. So without further ado, let’s get going!

Basic Input Usage

At it’s simplest, a component can use the “Input” declaration on a component, to say that any parent can pass in a value. For example, our ChildComponent may look like so :

export class ChildComponent {
  @Input() message : string;
}

And when we place this component on any page, we can do something like so :

<app-child [message]="'Hello World!'"></app-child>

Easy right! There really isn’t much to it!

Why The Double Quotes?

A common question I get asked is why do we double quote the text going in? e.x. Why do we have both ” and ‘ wrapped around our Hello World?

[message]="'Hello World!'"

The answer is actually quite simple. When we use the square brackets syntax [] it means we are doing a “one way” bind (From our parent to our child). This one way binding syntax expects either a variable, or a constant. However I often see people making the mistake of doing this :

[message]="Hello"

Since the message input variable is a string, what’s the big deal right? Well when you don’t wrap ‘Hello’ in single quotes, what you are telling Angular is that you are passing a variable. In this case, Angular looks for a variabled named “Hello”, doesn’t find one, then passes through an undefined value. This is why you often single variables wrapped in single quotes, even when passing strings through.

Timing Is Everything

The next problem people generally run into with Input variables is to do with timing. Often, start up code will live in an ngOnInit like so :

export class ChildComponent implements OnInit {
  @Input() message : string;
  
  constructor() { }

  ngOnInit() {
    console.log(this.message);
  }

}

But what happens if message is not set by the time the component is initialized? A common reason for this is that maybe string comes from an API, and therefore there is a bit of a race condition with the API returning and passing the message into the child component, and the child component actually being initialized.

For these sorts of race conditions, I generally go with property getters and setters. That means turning my component into something more like so :

export class ChildComponent implements OnInit {

  _message : string;
  @Input() set message (value : string) {
    this._message = value;
    this.setup();
  }
  
  constructor() { }

  ngOnInit() {
  }

  setup() {
    console.log(this._message);
  }

}

Now it doesn’t matter on the timing of when a message will be set. Each time the input variable is changed, we will kick off the setup routine. I use this in almost all of my projects as it’s a pretty quick and simple way to allow async one way bindings to occur, where I don’t need to manually be checking change tracking myself.

Timing Complex Objects

Our above example works because when a new message is passed in, the reference changes and the setter is called. But imagine we have a more complex object like so :

export class ChildComponentConfiguration {
  message : string;
}

With our child component like so :

export class ChildComponent implements OnInit {

  _config : ChildComponentConfiguration;
  @Input() set config (value : ChildComponentConfiguration) {
    this._config = value;
    this.setup();
  }
  
  constructor() { }

  ngOnInit() {
  }

  setup() {
    console.log(this._config.message);
  }

}

Imagine that we pass in our configuration object, then at a later point, the message object is changed. Under this scenario, our setter will never be called because the configuration object itself has not changed, only the properties within it.

Now, what I’m going to suggest has it’s own pros and cons. You should definitely read more about implementing your own DoCheck methods, but.. it works a bit like this :

export class ChildComponent implements OnInit, DoCheck {
  @Input() config : ChildComponentConfiguration;
  
  differ: any;
  
  constructor(private differs: KeyValueDiffers) { 
    this.differ = differs.find({}).create();
  }

  ngDoCheck(): void {
    const changes = this.differ.diff(this.config);
    if(changes) {
      changes.forEachAddedItem(change => {
        //The message has changed. 
        if(change['key'] == 'message')
        {
          this.setup();
        }
      });
    }
  }

  ngOnInit() {
  }

  setup() {
    console.log(this.config.message);
  }
}

Let’s walk through this a little. The first thing you will notice is that we implement the “DoCheck” interface, this means that when ChangeTracking is called on our component, we can implement custom logic to say what’s changed.

In our constructor, we take what’s called a “KeyValueDiffers”. The main thing to note is that this allows us to compare “differences” between an object each time the DoCheck method is called. Essentially, if the message has changed between two calls of ngDoCheck, then the differ will pick it up.

Finally, once we have the changes we need to loop through them and check them. We do this by checking the change “key” which is the name of the property that changed. If it’s the “message” that’s changed, then we call setup.

There’s obviously come caveats with using this :

  • ngDoCheck is called very often. It shouldn’t be taken lightly as it can cause an app to slow to a crawl. Much like using an impure pipe!
  • The differ can actually know when values are unset or set for the first time instead of modified, so play around with it a little bit
  • Again, you only need this if a property of your input variable is “delayed” being changed, but that could even be because a user must click a button first, not just waiting on API calls.

Overall, implement DoCheck is a heavy handed approach, but it’s one to keep in your tool arsenal if you have no other option.

Next

Coming up next is using EventEmitters to handle events being passed up from child to parent! Check it out here : https://tutorialsforangular.com/2021/04/04/inter-component-communication-in-angular-output-binding/

Creating custom validators in Angular isn’t anything new for me, I must have created dozens of them over the years, but strangely enough I haven’t had to create “async” validators in recent memory. When I tried to find more information about making a custom validator that returned an observable (or a promise), there really wasn’t a heck of a lot of information out there. Or more so, it was spread out in piecemeal code slices.

This post should hopefully group some of the core concepts together, specifically, at the end I will show how to create a “debounce” validator that only runs when a user stops typing, as this for me was the hardest thing to find examples of!

Basic Async Validator In Angular

For the purposes of this article, I’m going to write an async validator that calls an API to check if a username is currently in use or not. Imagine I’m using this on a sign up form to make sure that no two users pick the same username.

The full code is actually quite simple and looks like so :

import { Directive,  forwardRef} from '@angular/core';
import { AbstractControl, AsyncValidator, NG_ASYNC_VALIDATORS, ValidationErrors } from '@angular/forms/';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { AccountService } from '../services/account.service';

@Directive({
    selector: '[usernameCheck]', 
    providers: [
        {
            provide: NG_ASYNC_VALIDATORS, 
            useExisting: forwardRef(() => UsernameCheckDirective), 
            multi: true
      }
      ]
  })
  export class UsernameCheckDirective implements AsyncValidator {
    constructor(private accountService : AccountService) {
    }
  
    validate(control: AbstractControl): Observable<ValidationErrors | null> {
        return this.accountService.exists(control.value).pipe(map(x => x.exists ? { exists : true} : null))
    }
}

There are a couple of things to point out. First notice that my provider name is NG_ASYNC_VALIDATORS and *not* NG_VALIDATORS. This is so important because Angular won’t complain if you use NG_VALIDATOR here, instead it will just never show an error (Very very annoying and took me a very long time to debug).

Next notice that my validator method returns an observable. For this, I call my AccountService which has a method called “Exists”. This returns an object with a boolean property called “exists”. If true, it means the username is taken and I should return an object like so

{ exists : true}

Otherwise, I should return null.

Easy right?

When I write HTML to use this, I can just do the following :

<input name="username" 
    #username="ngModel" 
    type="text" 
    class="form-control" 
    [(ngModel)]="createAccount.name" 
    [usernameCheck]
    required />
<div class="validation-message" *ngIf="username?.errors?.exists">
    Username "{{createAccount.name}}" is already in use
</div>

Nothing too special and it works perfectly fine!

Ignoring Empty Values

The first issue I ran into is that as soon as my form loads, I could see it pinging the server to check if a username existed, before I’ve even typed a single character! What I needed was a quick short circuit to return an empty value if the control was empty. Something like this did the trick perfect!

validate(control: AbstractControl): Observable<ValidationErrors | null> {
    if(!control.value) {
        return of(null);
    }
    return this.accountService.exists(control.value).pipe(map(x => x.exists ? { exists : true} : null))
}

Now, when the value of my control is empty, the validator simply returns null (e.g. There are no errors), and we are good to go.

But then there was another issue….

Debouncing The Validation

What I noticed was that as I typed, I would validate every single keystroke by calling the backend API. This was way overkill and was resulting in 10’s of API calls when all someone was trying to do was fill in their username. What I needed was instead of validating every single key press, I needed to wait until the user stopped typing, then go ahead and validate the username. This in Angular terms is usually called “debouncing”.

Now I had worked with debounced textboxes before, infact, here’s an article I wrote on that very subject : https://tutorialsforangular.com/2021/03/17/creating-a-textbox-with-delayed-output-in-angular/! But the issue was that how could I debounce from within a validator?

Interestingly, I headed to the Angular documentation for help and all it told me was to use the ngModelOptions to only validate on blur like so :

<input [(ngModel)]="name" [ngModelOptions]="{updateOn: 'blur'}">

I personally loathe this method because I hate the fact a user has to click somewhere else on the screen to have validation run. Often forcing them to find some white space to click on the page.

Then I read about an interesting “quirk” within Angular’s Async Validator code. It stated that if an existing validation was in progress when another request for validation came in, it would cancel that initial validation and instead subscribe to that incoming validation request. I suppose it in all likelihood was so that you didn’t end up with a race condition where as you were typing, validators were resulting at odd times and giving mixed results. But could we use this to our advantage? As it so happens, yes we could!

Here’s our new async validate method :

validate(control: AbstractControl): Observable<ValidationErrors | null> {
    if(!control.value) {
        return of(null);
    }

    return of(control.value)
          .pipe(
              delay(250), 
              //Then instead return the observable of us actually checking the value. 
              switchMap((value) => 
                  this.accountService.exists(value).pipe(map(x => {
                      return x.exists ? {exists : true} : null;
                  }))
              )
          );
}

Here’s how it works. When the validator is kicked off, the first thing it does is it waits 250ms. That may seem dumb but there’s a reason. Imagine the user keeps typing, and validation kicks off again? What happens to that first validation request? It gets cancelled! Is that a bad thing? Well no because it was just waiting 250ms so no harm done, kill the process all you want! This continues until the user stops typing, and the full 250ms passes, at which point the backend service will be called!

I’ve seen variations of this that instead utilize debounce, timers, and all sorts of manually created observables. This for me, works without fail. And for me, it makes the most sense. All we are trying to do is tap into that native ability of Angular cancelling in flight validation requests on new validation requests. So we aren’t trying to work around Angular’s limitations, but instead work with it!

I wasn’t quite sure what to call this post, so instead let’s give give some scenarios in which you want to use a “Texbox with delayed output”

  • You want to create your own custom typeahead component that waits until a user stops typing before looking up results
  • You want a textbox that waits until a user stops typing, so you can call a backend API to check for duplicated names/emails/records
  • You want to add a text filter to a table/list, that only refreshes/filters when you stop typing in a textbox for a short period of time
  • In general, we want to use a textbox that waits until the user has stopped typing for a few milliseconds, and only then return the result to us

All of these can be solved using a Textbox with a delayed (or debounced) output. And it’s actually very simple using some helpful code from RxJS.

First I’ll give you the complete code, then point out the important bits :

@Component({
  selector: 'app-delayed-textbox',
  templateUrl: './delayed-textbox.component.html',
  styleUrls: ['./delayed-textbox.component.scss'], 
  providers : [
    { 
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => DebounceTextboxComponent),
      multi: true
    }
  ]
})
export class DelayedTextboxComponent implements OnInit {
  delayTime : number = 250
  
  currentText : string;
  
  private textChanged = new Subject();

  constructor() { }

  ngOnInit(): void {
    this.textChanged.pipe(debounceTime(this.delayTime)).subscribe(() => {
      this.propogateTouch();
      this.propagateChange(this.currentText);
    });
  }

  onTextInput() {
    this.textChanged.next();
  }

   //Start implementation of ControlValueAccessor
   propagateChange = (_: any) => {};
   propogateTouch = () => {};
 
   writeValue(obj: any): void {
     this.currentText = obj;
   }
 
   registerOnChange(fn: any): void {
     this.propagateChange = fn;
   }
   registerOnTouched(fn : any) {
     this.propogateTouch = fn;
   }
   setDisabledState?(isDisabled: boolean): void {}
   //End implementation of ControlValueAccessor
}

This little piece here is where the secret sauce is :

private textChanged = new Subject();

this.textChanged.pipe(debounceTime(this.delayTime)).subscribe(() => {
  this.propogateTouch();
  this.propagateChange(this.currentText);
});

What this says is as events are pumped into the textChanged subject, “debounce” them. That is, wait until there is a gap of 250ms, then return me the *last* item. If there are multiple events pumped into the subject during this time, still I only want the last one returned to me.

In our view for our custom component, we will have just the following :

<input type="text"
        name="delayTextbox"
        [(ngModel)]="currentText"
        (ngModelChange)="onTextInput()" />

So nothing special, but in particular notice that when the model is changed, onTextInput() is called. This then enqueues a message onto our subject, which then itself debounces for 250ms, and then finally we propogate the change!

We can use this delayed textbox like so :

<app-delayed-textbox 
  name="myTextbox" 
  [(ngModel)]="myModel.Field" 
  (ngModelChange)="onMyModelFieldChanged()">
</app-delayed-textbox >

Notice how because we set up the ControlValueAccessor interface on our custom component, we can simply use the standard ngModel and ngModelChange to be alerted when the field changes.

I’ve seen some really crazy implementations of these sorts of delayed textboxes where people try and time keydowns and keyups, and just a crazy combination of setTimeout and booleans etc. But RxJS essentially does the same thing for us, using the simply debounceTime operator!

It’s pretty common in an Angular project to add the ability to “listen” for router events. That is, know that a user is about to (or already has) navigated to a new page. The most common reason is to push pageview events to analytics platforms (think Google Analytics or Azure Application Insights), but I’ve also used them to hook into whether a user is navigating away from a page (And stop them from losing their work), or to hide toaster/error messages if a user has moved away from a particular page.

In anycase, it’s actually fairly trivial to subscribe to router events.

The first thing to do is to inject the Router object into your service/component like so :

constructor(private router: Router)

Then to subscribe, we simply subscribe to a filtered list of navigation events like so :

this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe((event: NavigationEnd) => {
  //Do something with the NavigationEnd event object.
});

Notice that we are filtering only on NavigationEnd events, this is because the events stream from the router is *all* Router events. The main events you want to subscribe to are listed below (Although there are a couple more, I personally never really use them).

  • NavigationStart – Triggered when a navigation starts
  • NavigationEnd – Triggered when navigation ends successfully
  • NavigationError – Triggered when navigation ends with an error
  • NavigationCancel – Triggered when a navigation is cancelled (Often because a router guard returned false)
  • GuardsCheckStart – Triggered before guards are run as part of the routing
  • GuardsCheckEnd – Triggered at the end of guards running as part of the routing

The most important ones I’ve used are NavigationStart, to determine if a user is about to navigate away, and NavigationEnd when a user has successfully browsed to a new page. It’s also important to keep in mind NavigationError, as NavigationEnd will only trigger if a user was successfully able to visit a page, but you may be missing analytics of failed pages if you ignore NavigationError.

And that’s it! Now you can subscribe to all sorts of different router events with just a couple of lines of code!

Some forms require the ability to “clear” all input and “reset” the form. I struggled through a few different ways of clearing a form before I found a foolproof way that seemed to work in all scenarios I tested.

First, what didn’t work. NGForm does have two reset methods :

this.myForm.reset();

And

this.myForm.resetForm();

Both of these “appeared” to work, but I found it completely broke data binding at times where values got reset to null and lost their data binding. I personally use Template Driven Forms rather than Reactive Forms, so it may work in different scenarios, but for me, this really broke data binding.

If you use Template Driven Forms like me, then the best way I found to actually wipe values in the form was to first reset the underlying two way data binding object. E.g. If I’m binding to a “Person” object then I first do new Person() etc.

Then I can run the following code which only seems to reset the validity of controls rather than fiddling with the underlying data:

Object.keys(this.myForm.controls).forEach((key) => {
    const control = this.myForm.controls[key];
    control.markAsPristine();
    control.markAsUntouched();
});

This runs through every control and resets the validity without affecting binding. This seemed to work the best for me. An alternative I found would be to change the call to setErrors()

Object.keys(this.myForm.controls).forEach((key) => {
    const control = this.myForm.controls[key];
    control.setErrors(null);
});

Again, the first iteration worked for me, but try both if it doesn’t for you.

Adding An NGForm Extension Method

Now rather than copy and pasting this everywhere, instead I created an extension. I created a file called ng-form.extensions.ts with the following content :

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

declare module "@angular/forms/" {
    interface NgForm {
      resetValidation(this:Form) : void;
    }
}

NgForm.prototype.resetValidation = function(this:NgForm) {
    Object.keys(this.controls).forEach((key) => {
        const control = this.controls[key];
        control.markAsPristine();
        control.markAsUntouched();
    });
}

Then in my component, I have to import this extension file like so :

import 'src/app/_core/extensions/ng-form.extensions'

And I then simply reset the form like so :

this.myForm.resetValidation();

Much cleaner!

One of the more frustrating limitations of vanilla JavaScript is that there is actually no GUID or UUID generator in the language. That’s right, out of the box, you cannot generate a GUID with a nice single line of code! Very annoying.

Luckily, there are two ways that I’ve used in the past to generate GUID or GUID-like strings.

This first piece of code is one I use in places where the randomness isn’t such a big deal. It might be just generating correlation ids, or just as a way to generate some randomized letters/numbers, but not global uniqueness and/or collisions aren’t such a big deal.

generateGuid() : string {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random() * 16 | 0,
      v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}

In most cases where I’m generating a GUID on the front end, I’m not worried too much about how secure things are. You shouldn’t be too concerned on collisions in the browser anyway because a user could just as easily inject JavaScript and/or modify an API call that uses the GUID into using their own string.

However, for a more secure GUID, there is obviously an NPM package for that!

npm install uuid

Then use the uuidv4 function to generate guids as you need them!

import { v4 as uuidv4 } from 'uuid';
let myGuid = uuidv4();

Again, in most cases I just use the first function. But I know people come up with all sorts of links on how “Math.random()” isn’t truly random etc. So both options are there!